Merge branch 'release/AddDayChecks'

This commit is contained in:
Samuele Locatelli
2022-01-15 11:05:34 +01:00
44 changed files with 41906 additions and 247 deletions
+82 -1
View File
@@ -142,7 +142,7 @@ namespace GPW.CORE.Data.Controllers
.DbSetCalcOreProj
.FromSqlRaw("EXEC stp_AP_getByIdxPrj @idxProgetto", idxProgetto)
.ToList();
if (rawResult != null && rawResult.Count>0)
if (rawResult != null && rawResult.Count > 0)
{
dbResult = rawResult[0];
}
@@ -150,6 +150,28 @@ namespace GPW.CORE.Data.Controllers
return dbResult;
}
/// <summary>
/// Recupera l'elenco dei Rilievi temperatura nel periodo indicato x dipendente
/// </summary>
/// <param name="idxDipendente">Dipendente interessato</param>
/// <param name="dtInizio">Data di riferimento (ultima/corrente)</param>
/// <param name="dtFine">NUm settimane precedenti da recuperare</param>
/// <returns></returns>
public List<CheckVc19Model> CheckVC19List(int idxDipendente, DateTime dtInizio, DateTime dtFine)
{
// init dati necessari
List<CheckVc19Model> dbResult = new List<CheckVc19Model>();
// cerco su DB recuperando set di dati....
using (GPWContext localDbCtx = new GPWContext(_configuration))
{
dbResult = localDbCtx
.DbSetCheckVc19
.Where(x => x.IdxDipendente == idxDipendente && dtInizio <= x.DtCheck && x.DtCheck <= dtFine)
.ToList();
}
return dbResult;
}
/// <summary>
/// Recupera l'elenco dei dettagli giornalieri attività di un dipendente, dato periodo riferimento
/// </summary>
@@ -376,6 +398,65 @@ namespace GPW.CORE.Data.Controllers
return answ;
}
/// <summary>
/// Recupera l'elenco dei Rilievi temperatura nel periodo indicato x dipendente
/// </summary>
/// <param name="idxDipendente">Dipendente interessato</param>
/// <param name="dtInizio">Data di riferimento (ultima/corrente)</param>
/// <param name="dtFine">NUm settimane precedenti da recuperare</param>
/// <returns></returns>
public List<RilievoTempModel> RilTempList(int idxDipendente, DateTime dtInizio, DateTime dtFine)
{
// init dati necessari
List<RilievoTempModel> dbResult = new List<RilievoTempModel>();
// cerco su DB recuperando set di dati....
using (GPWContext localDbCtx = new GPWContext(_configuration))
{
dbResult = localDbCtx
.DbSetRilievoTemp
.Where(x => x.IdxDipendente == idxDipendente && dtInizio <= x.DtRilievo && x.DtRilievo <= dtFine)
.ToList();
}
return dbResult;
}
public bool RilTempUpdate(RilievoTempModel currItem)
{
bool answ = false;
using (GPWContext localDbCtx = new GPWContext(_configuration))
{
try
{
var currRec = localDbCtx
.DbSetRilievoTemp
.FirstOrDefault(x => x.IdxDipendente == currItem.IdxDipendente && x.DtRilievo == currItem.DtRilievo);
if (currRec != null)
{
// aggiorno solo entrata/uscita
currRec.TempRil = currItem.TempRil;
localDbCtx
.DbSetRilievoTemp
.Update(currRec);
}
// altrimenti aggiungo
else
{
localDbCtx
.DbSetRilievoTemp
.Add(currItem);
}
localDbCtx.SaveChanges();
answ = true;
}
catch (Exception exc)
{
Log.Error($"Eccezione in RilTempUpdate{Environment.NewLine}{exc}");
}
}
return answ;
}
/// <summary>
/// Annulla modifiche su una specifica entity (cancel update)
/// </summary>
-5
View File
@@ -49,11 +49,6 @@
newItem = await GDataServ.RegAttLastByDip(AppMServ.IdxDipendente);
}
// calcolo durata arrotondata ai 5 minuti...
#if false
TimeOnly step = new TimeOnly(0, 5);
long ticks = (newItem.Durata.Ticks + step.Ticks - 1) / step.Ticks;
durata = new TimeSpan(ticks * step.Ticks);
#endif
durata = CORE.Data.Utils.TSpanRounded(newItem.Durata, 5, false);
newItem.IdxRa = 0;
newItem.Inizio = InizioPer;
+62
View File
@@ -0,0 +1,62 @@
@inject IJSRuntime JSRuntime
<canvas id="@Id"></canvas>
@code {
public enum ChartType
{
Pie,
Bar
}
[Parameter]
public string Id { get; set; } = "MyChart";
[Parameter]
public ChartType Type { get; set; }
[Parameter]
public string[] Data { get; set; }
[Parameter]
public string[] BackgroundColor { get; set; }
[Parameter]
public string[] Labels { get; set; }
protected override async Task OnAfterRenderAsync(bool firstRender)
{
await InitDefault();
}
protected async Task InitDefault()
{
// Here we create an anonymous type with all the options
// that need to be sent to Chart.js
var config = new
{
type = Type.ToString().ToLower(),
options = new
{
responsive = true,
scales = new
{
yAxes = new
{
suggestedMin = 0
}
}
},
data = new
{
datasets = new[]
{
new { data = Data, backgroundColor = BackgroundColor}
},
labels = Labels
}
};
await JSRuntime.InvokeVoidAsync("setup", Id, config);
}
}
+82
View File
@@ -0,0 +1,82 @@
@inject IJSRuntime JSRuntime
<canvas id="@Id"></canvas>
@code {
[Parameter]
public string Id { get; set; } = "MyHist";
[Parameter]
public string[] Data { get; set; }
[Parameter]
public string[] Labels { get; set; }
[Parameter]
public string lineColor { get; set; }
[Parameter]
public string backColor { get; set; }
protected override async Task OnAfterRenderAsync(bool firstRender)
{
//if (!firstRender)
//{
await renderChart();
//}
}
/// <summary>
/// Inizializzazione rendering componente
///
/// partendo da qui:
/// https://www.williamleme.com/posts/2020/003-chartjs-blazor/
/// https://www.puresourcecode.com/dotnet/blazor/using-chart-js-with-blazor/
/// https://www.tutorialsteacher.com/csharp/csharp-anonymous-type
/// </summary>
/// <param name="firstRender"></param>
/// <returns></returns>
protected async Task renderChart()
{
// creazione di un oggetto anonymous type con tutte le opzioni da passare a chart.js
var config = new
{
type = "bar",
options = new
{
responsive = true,
scales = new
{
yAxes = new
{
suggestedMin = 0,
display = true,
ticks = new
{
beginAtZero = true,
maxTicksLimit = 10
}
}
}
},
data = new
{
datasets = new[]
{
new
{
data = Data,
borderColor = lineColor,
backgroundColor = backColor,
borderWidth = 1,
label= "Freq. Osservate"
}
},
labels = Labels
}
};
await JSRuntime.InvokeVoidAsync("setup", Id, config);
}
}
+90
View File
@@ -0,0 +1,90 @@
@inject IJSRuntime JSRuntime
<canvas id="@Id"></canvas>
@code {
[Parameter]
public string Id { get; set; } = "MyTs";
[Parameter]
public List<chartJsData.chartJsTSerie> DataTS { get; set; }
[Parameter]
public string lineColor { get; set; }
[Parameter]
public string backColor { get; set; }
/// <summary>
/// Inizializzazione rendering componente
///
/// partendo da qui:
/// https://www.williamleme.com/posts/2020/003-chartjs-blazor/
/// https://www.puresourcecode.com/dotnet/blazor/using-chart-js-with-blazor/
/// https://www.tutorialsteacher.com/csharp/csharp-anonymous-type
/// </summary>
/// <param name="firstRender"></param>
/// <returns></returns>
protected override async Task OnAfterRenderAsync(bool firstRender)
{
//if (!firstRender)
//{
await renderChart();
//}
}
/// <summary>
/// Inizializzazione rendering componente
///
/// partendo da qui:
/// https://www.williamleme.com/posts/2020/003-chartjs-blazor/
/// https://www.puresourcecode.com/dotnet/blazor/using-chart-js-with-blazor/
/// https://www.tutorialsteacher.com/csharp/csharp-anonymous-type
/// </summary>
/// <param name="firstRender"></param>
/// <returns></returns>
protected async Task renderChart()
{
// creazione di un oggetto anonymous type con tutte le opzioni da passare a chart.js
var config = new
{
type = "line",
options = new
{
responsive = true,
scales = new
{
yAxes = new
{
display = true,
ticks = new
{
maxTicksLimit = 10
}
},
xAxes = new
{
type = "timeseries",
distribution = "linear",
}
}
},
data = new
{
datasets = new[]
{
new
{
data = DataTS,
borderColor= lineColor,
backgroundColor= backColor,
lineTension= 0,
stepped= true,
label= "Temperatura Rilevata"
}
}
}
};
await JSRuntime.InvokeVoidAsync("setup", Id, config);
}
}
+121
View File
@@ -0,0 +1,121 @@
@using CORE.Data.DbModels
@using UI.Data
@inject IJSRuntime JSRuntime
@inject GpwDataService GDataServ
@inject MessageService AppMServ
<div class="card">
<div class="card-header bg-dark text-light py-1">
<div class="row">
<div class="col-8">
<h4>Daily Cheks</h4>
</div>
<div class="col-4 py-1">
<button type="button" class="btn btn-block btn-warning py-1" @onclick="DoClose"><i class="fas fa-times"></i> Chiudi</button>
</div>
</div>
</div>
<div class="card-body">
<div class="row">
<div class="col-4">
@if (listRilTemp != null)
{
<ChartTS Id="TempRil" DataTS="@listRilTemp" lineColor="rgb(7, 173, 236)" backColor="rgba(107, 223, 255, 0.3)"></ChartTS>
<ChartHist Id="FreqTemp1" Data="@histData" Labels="@histLabel" lineColor="rgb(7, 173, 236)" backColor="rgba(107, 223, 255, 0.5)"></ChartHist>
}
else
{
<LoadingDataSmall></LoadingDataSmall>
}
</div>
<div class="col-4 px-0">
<div class="card">
<div class="card-header text-center">
<b>@TargetDate.ToString("dddd dd/MM/yyyy")</b>
</div>
<div class="card-body">
@if (currRecord != null)
{
<label class="small">temperatura odierna</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text" style="width:3em;">
<i class="fas fa-thermometer-half"></i>
</span>
</div>
<input type="number" step="0.1" min="35" max="42" class="form-control text-right" @bind="@currRecord.TempRil"></input>
<div class="input-group-append">
<button class="btn btn-success btn-block" title="Salva temperatura" @onclick="() => DoSave()"><i class="far fa-save"></i></button>
</div>
</div>
}
else
{
<LoadingDataSmall></LoadingDataSmall>
}
</div>
<div class="card-footer">
<label class="small">periodo grafici</label>
<div class="input-group input-group-sm">
<div class="input-group-prepend">
<span class="input-group-text" style="width:3em;">
<i class="far fa-calendar-alt"></i>
</span>
</div>
<select @bind="@numDays" class="form-control" title="finestra analisi">
<option value="30">1 Mese</option>
<option value="60">2 Mese</option>
<option value="90">3 Mese</option>
<option value="180">6 Mese</option>
<option value="365">1 Anno</option>
<option value="730">2 Anno</option>
</select>
</div>
</div>
</div>
</div>
<div class="col-4">
@if (listVC19 != null)
{
<h4>Check C19</h4>
<table class="table table-sm table-striped small">
<thead>
<tr>
<th>Check</th>
<th>Cognome</th>
<th>Nome</th>
<th>Data Nascita</th>
</tr>
</thead>
<tbody>
@foreach (var record in listVC19)
{
<tr>
<td>
@record.DtCheck.ToString("dd/MM/yy HH:mm")
</td>
<td>
@record.Cognome
</td>
<td>
@record.Nome
</td>
<td>
@record.Dob.ToShortDateString()
</td>
</tr>
}
</tbody>
</table>
}
else
{
<LoadingDataSmall></LoadingDataSmall>
}
</div>
</div>
</div>
</div>
@@ -0,0 +1,129 @@
using GPW.CORE.Data.DbModels;
using Microsoft.AspNetCore.Components;
namespace GPW.CORE.UI.Components
{
public partial class DayCheckEditor
{
#region Protected Fields
protected int _numDays = 30;
#endregion Protected Fields
#region Private Properties
private int numDays
{
get
{
return _numDays;
}
set
{
_numDays = value;
var pUpd = Task.Run(async () => await ReloadData());
pUpd.Wait();
}
}
#endregion Private Properties
#region Protected Properties
protected DateTime _targetDate { get; set; } = DateTime.Today;
protected RilievoTempModel? currRecord { get; set; } = null;
protected string[]? histData { get; set; } = null;
protected string[]? histLabel { get; set; } = null;
protected List<chartJsData.chartJsTSerie>? listRilTemp { get; set; } = null;
protected List<CheckVc19Model>? listVC19 { get; set; } = null;
#endregion Protected Properties
#region Public Properties
[Parameter]
public EventCallback<bool> CloseReq { get; set; }
[Parameter]
public DateTime TargetDate
{
get
{
return _targetDate;
}
set
{
_targetDate = value;
var pUpd = Task.Run(async () => await ReloadData());
pUpd.Wait();
}
}
#endregion Public Properties
#region Protected Methods
/// <summary>
/// Indico item selezionato
/// </summary>
protected async void DoClose()
{
await CloseReq.InvokeAsync(true);
}
/// <summary>
/// Effettua salvataggio misurazione temperatura
/// </summary>
protected async void DoSave()
{
// chiamo classe gestione che salva e resetta cache dati...
if (currRecord != null)
{
await GDataServ.RilTempUpdate(currRecord);
}
// chiamo chiusura!
await CloseReq.InvokeAsync(true);
}
protected async Task ReloadData()
{
DateTime inizio = TargetDate.AddDays(1 - numDays);
DateTime fine = TargetDate.AddDays(1);
// recupero dati completi...
var rawVC19 = await GDataServ.CheckVC19List(AppMServ.IdxDipendente, fine.AddDays(-15), fine);
var rawData = await GDataServ.RilTempList(AppMServ.IdxDipendente, inizio, fine);
// calcolo dati derivati
listVC19 = rawVC19.OrderByDescending(x => x.DtCheck).ToList();
listRilTemp = rawData.Select(r => new chartJsData.chartJsTSerie()
{ x = r.DtRilievo, y = r.TempRil }).ToList();
// calcolo hist frequenza con EFCore: https://entityframeworkcore.com/knowledge-base/60871048/group-by-and-to-dictionary-in-ef-core-3-1
var histDict = rawData.GroupBy(r => r.TempRil.ToString("N1")).Select(g => new
{
g.Key,
Count = g.Count()
}).OrderBy(d => d.Key).ToDictionary(x => x.Key, x => x.Count.ToString());
histData = histDict.Values.ToArray();
histLabel = histDict.Keys.ToArray();
// cerco se c'è dato odierno della temperatura...
currRecord = rawData.Where(x => x.DtRilievo == TargetDate).FirstOrDefault();
if (currRecord == null)
{
currRecord = new RilievoTempModel()
{ IdxDipendente = AppMServ.IdxDipendente, DtRilievo = DateTime.Today, TempRil = 0 };
}
}
#endregion Protected Methods
}
}
+3 -3
View File
@@ -60,9 +60,9 @@
}
else
{
<div class="small badge badge-pill badge-dark" @onclick="SelTimbrature"><b>@TotLav</b> <i class="far fa-calendar-alt"></i></div>
<div class="small badge badge-pill @cssBadgeLav"><b>@TotComm</b> <i class="far fa-hourglass"></i></div>
<div class="small"><i class="fas fa-thermometer-half @cssThermo"></i> <i class="fas fa-certificate @cssCheck"></i></div>
<div class="btn btn-sm btn-block btn-dark px-1 py-0" @onclick="SelTimbrature"><b>@TotLav</b> <i class="far fa-calendar-alt"></i></div>
<div class="btn btn-sm btn-block @cssBadgeLav px-1 py-0 mt-1"><b>@TotComm</b> <i class="far fa-hourglass"></i></div>
<div class="btn btn-sm btn-block btn-light border border-dark px-1 py-0 mt-1" @onclick="SelTemperature"><i class="fas fa-thermometer-half @cssThermo"></i> <i class="fas fa-certificate @cssCheck"></i></div>
}
</div>
</div>
+70 -17
View File
@@ -48,6 +48,9 @@ namespace GPW.CORE.UI.Components
[Parameter]
public EventCallback<RegAttivitaModel> ItemUpdated { get; set; }
[Parameter]
public EventCallback<DateTime> ReqTempList { get; set; }
private bool noData { get => DayDTO == null || DayDTO.ListRA == null || DayDTO.ListRA.Count == 0; }
private Double oreLav
@@ -60,12 +63,20 @@ namespace GPW.CORE.UI.Components
answ = (double)DayDTO.TimbrExpl.HLav;
if (DayDTO.DtRif == DateTime.Today)
{
// aggiungo ultima timb fino ad adesso...
var lastIn = DayDTO.ListTimbr.Where(x => x.Entrata == true).OrderByDescending(x => x.DataOra).FirstOrDefault();
if (lastIn != null)
if (DayDTO.ListTimbr != null)
{
DateTime adesso = DateTime.Now;
answ += adesso.Subtract(lastIn.DataOra).TotalHours;
// aggiungo ultima timb fino ad adesso...
var lastIn = DayDTO.ListTimbr.Where(x => x.Entrata == true).OrderByDescending(x => x.DataOra).FirstOrDefault();
var lastOut = DayDTO.ListTimbr.Where(x => x.Entrata == false).OrderByDescending(x => x.DataOra).FirstOrDefault();
// se MANCA timb uscita finale...
if (lastIn != null)
{
if (lastOut == null || lastOut.DataOra < lastIn.DataOra)
{
DateTime adesso = DateTime.Now;
answ += adesso.Subtract(lastIn.DataOra).TotalHours;
}
}
}
}
}
@@ -141,10 +152,51 @@ namespace GPW.CORE.UI.Components
return answ;
}
}
private decimal tempRil
{
get
{
decimal answ = 0;
if (OkTemp)
{
answ = DayDTO.ListRilTemp[0].TempRil;
}
return answ;
}
}
public string cssThermo
{
get => OkTemp ? "text-success" : "text-secondary";
get
{
string answ = "";
// verifico in base a ok temp o meno...
if (OkTemp)
{
// colore in base al valore...
var currTemp = tempRil;
if (currTemp != null)
{
if (currTemp >= (decimal)37.5)
{
answ = "text-danger";
}
else if (currTemp >= 37)
{
answ = "text-warning";
}
else
{
answ = "text-success";
}
}
}
else
{
answ = "text-secondary";
}
return answ;
}
}
public string cssCheck
{
@@ -155,19 +207,20 @@ namespace GPW.CORE.UI.Components
{
get
{
string answ = "badge-light";
string bCtr = "btn";
string answ = $"{bCtr}-light";
var deltaComm = oreComm - oreLav;
if (Math.Abs(deltaComm) < 0.5)
{
answ = "badge-info";
answ = $"{bCtr}-info";
}
else if (Math.Abs(deltaComm) < 1)
{
answ = "badge-warning";
answ = $"{bCtr}-warning";
}
else
{
answ = "badge-danger";
answ = $"{bCtr}-danger";
}
return answ;
}
@@ -201,13 +254,6 @@ namespace GPW.CORE.UI.Components
var firstRec = timbIN.OrderBy(x => x.DataOra).FirstOrDefault();
if (firstRec != null)
{
#if false
// calcolo dataora approssimata arrotondando ai 5 minuti x difetto...
// https://stackoverflow.com/questions/1393696/rounding-datetime-objects
TimeOnly step = new TimeOnly(0, 5);
long ticks = (firstRec.DataOra.Ticks + step.Ticks - 1) / step.Ticks;
FirstTimb = new DateTime(ticks * step.Ticks, firstRec.DataOra.Kind);
#endif
FirstTimb = CORE.Data.Utils.DateRounded(firstRec.DataOra, 5, false);
}
}
@@ -360,6 +406,13 @@ namespace GPW.CORE.UI.Components
await PeriodSelected.InvokeAsync(DayDTO.ListTimbr);
}
}
protected async void SelTemperature()
{
if (DayDTO != null)
{
await ReqTempList.InvokeAsync(DayDTO.DtRif);
}
}
}
}
+6 -5
View File
@@ -9,9 +9,10 @@
<div class="card">
<div class="card-header">
<h1>@message</h1>
Data Reset
</div>
<div class="card-body">
<h1>@message</h1>
<LoadingData></LoadingData>
</div>
</div>
@@ -21,14 +22,14 @@
protected override async Task OnInitializedAsync()
{
await GDataServ.InvalidateAllCache();
message = "Reset done!";
AppMServ.clonedRA = null;
AppMServ.recordRA = null;
AppMServ.RigaDip = null;
//AppMServ.RigaDip = null;
message = "Reset done!";
// attendo 100 msec
await Task.Delay(100);
// attendo 500 msec
await Task.Delay(500);
// passo a pagina home
NavManager.NavigateTo("/");
+1 -1
View File
@@ -1,4 +1,4 @@
<div class="row p-5 m-5">
<div class="row p-3 m-2">
<div class="col-12 text-center mt-5 py-5 alert alert-primary">
<h3>loading data</h3>
<i class="fas fa-spinner fa-spin fa-5x"></i>
-39
View File
@@ -1,39 +0,0 @@
<div style="height: 4em;">
<div class="progress" style="height: 4em; width: 20%; float:left; vertical-align: middle;">
<div class="progress-bar bg-light text-dark" style="width:100%">
vuoto
</div>
</div>
<div class="progress" style="height: 4em; width: 30%;float:left;">
<div class="progress-bar bg-success" style="width:66%">
Free Space
</div>
<div class="progress-bar bg-warning" style="width:34%">
<div>
Warning
<button class="btn btn-sm btn-primary">+</button>
</div>
</div>
</div>
<div class="progress" style="height: 4em; width: 10%; float:left;">
<div class="progress-bar bg-light text-dark" style="width:100%">
vuoto
</div>
</div>
<div class="progress" style="height: 4em; width: 40%;float:left;">
<div class="progress-bar bg-danger" style="width:15%">
Danger
</div>
<div class="progress-bar bg-secondary" style="width:20%">
pausa
</div>
<div class="progress-bar bg-success" style="width:55%">
Free Space
</div>
</div>
</div>
<div style="clear: both;"></div>
@code {
}
@@ -42,9 +42,6 @@
[Parameter]
public EventCallback<bool> WeekSelected { get; set; }
//private int Anno = DateTime.Today.Year;
//private int Week = 1;
/// <summary>
/// Indico item selezionato
/// </summary>
+103 -154
View File
@@ -48,6 +48,8 @@ namespace GPW.CORE.UI.Data
protected const string rKeyGrpAll = "Cache:GrpAll";
protected const string rKeyParetoRegAtt = "Cache:ParetoRegAtt";
protected const string rKeyProjAll = "Cache:ProjAll";
protected const string rKeyRilTemp = "Cache:RilTemp";
protected const string rKeyVC19 = "Cache:VC19";
protected const string rKeyWeekStats = "Cache:WeekStats";
protected static string connStringBBM = "";
@@ -101,6 +103,22 @@ namespace GPW.CORE.UI.Data
#endregion Private Methods
#region Protected Methods
/// <summary>
/// Registra in cache chiave se non fosse già in elenco
/// </summary>
/// <param name="newKey"></param>
protected void trackCache(string newKey)
{
if (!cachedDataList.Contains(newKey))
{
cachedDataList.Add(newKey);
}
}
#endregion Protected Methods
#region Public Methods
/// <summary>
@@ -268,6 +286,7 @@ namespace GPW.CORE.UI.Data
{
CalcOreProgettiModel? dbResult = new CalcOreProgettiModel();
string currKey = $"{rKeyCalcOreProj}:{idxProj}";
trackCache(currKey);
string rawData;
var redisDataList = await distributedCache.GetAsync(currKey);
@@ -295,6 +314,45 @@ namespace GPW.CORE.UI.Data
return await Task.FromResult(dbResult);
}
/// <summary>
/// Recupera l'elenco dei controlli VC19 nel periodo indicato x dipendente
/// </summary>
/// <param name="idxDipendente">Dipendente interessato</param>
/// <param name="dtInizio">Data di riferimento (ultima/corrente)</param>
/// <param name="dtFine">NUm settimane precedenti da recuperare</param>
/// <returns></returns>
public async Task<List<CheckVc19Model>> CheckVC19List(int idxDipendente, DateTime dtInizio, DateTime dtFine)
{
List<CheckVc19Model>? dbResult = new List<CheckVc19Model>();
string currKey = $"{rKeyVC19}:{dtInizio:yyyyMMdd}:{dtFine:yyyMMdd}";
trackCache(currKey);
string rawData;
var redisDataList = await distributedCache.GetAsync(currKey);
if (redisDataList != null)
{
rawData = Encoding.UTF8.GetString(redisDataList);
dbResult = JsonConvert.DeserializeObject<List<CheckVc19Model>>(rawData);
}
else
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
dbResult = dbController.CheckVC19List(idxDipendente, dtInizio, dtFine);
rawData = JsonConvert.SerializeObject(dbResult, JSSettings);
redisDataList = Encoding.UTF8.GetBytes(rawData);
await distributedCache.SetAsync(currKey, redisDataList, cacheOpt(true));
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Trace($"Effettuata lettura da DB + caching per CheckVC19List: {ts.TotalMilliseconds} ms");
}
if (dbResult == null)
{
dbResult = new List<CheckVc19Model>();
}
return await Task.FromResult(dbResult);
}
/// <summary>
/// Recupera l'elenco dei dettagli giornalieri attività di un dipendente, dato periodo riferimento
/// </summary>
@@ -306,10 +364,7 @@ namespace GPW.CORE.UI.Data
{
List<CORE.Data.DTO.DailyDataDTO>? dbResult = new List<CORE.Data.DTO.DailyDataDTO>();
string currKey = $"{rKeyDailyData}:{idxDipendente}:{dtInizio.ToString("yyyy-MM-dd")}:{dtFine.ToString("yyyy-MM-dd")}";
if (!cachedDataList.Contains(currKey))
{
cachedDataList.Add(currKey);
}
trackCache(currKey);
string rawData;
var redisDataList = await distributedCache.GetAsync(currKey);
if (redisDataList != null)
@@ -386,6 +441,21 @@ namespace GPW.CORE.UI.Data
cachedDataList = new List<string>();
}
/// <summary>
/// Invalida la cache corrispondente al apttern fornito
/// </summary>
/// <returns></returns>
public async Task InvalidateCache(string cachePattern)
{
foreach (var item in cachedDataList)
{
if (item.Contains(cachePattern))
{
await distributedCache.RemoveAsync(item);
}
}
}
/// <summary>
/// Statistiche ultime settimane
/// </summary>
@@ -397,10 +467,7 @@ namespace GPW.CORE.UI.Data
{
List<CORE.Data.DTO.WeekStatDTO>? dbResult = new List<CORE.Data.DTO.WeekStatDTO>();
string currKey = $"{rKeyWeekStats}:{idxDipendente}:{dtRif.ToString("yyyy-MM-dd")}:{numWeek}";
if (!cachedDataList.Contains(currKey))
{
cachedDataList.Add(currKey);
}
trackCache(currKey);
string rawData;
var redisDataList = await distributedCache.GetAsync(currKey);
if (redisDataList != null)
@@ -504,185 +571,67 @@ namespace GPW.CORE.UI.Data
return answ;
}
#if false
public async Task<List<MaterialDTO>> MaterialsGetAll()
/// <summary>
/// Recupera l'elenco dei Rilievi temperatura nel periodo indicato x dipendente
/// </summary>
/// <param name="idxDipendente">Dipendente interessato</param>
/// <param name="dtInizio">Data di riferimento (ultima/corrente)</param>
/// <param name="dtFine">NUm settimane precedenti da recuperare</param>
/// <returns></returns>
public async Task<List<RilievoTempModel>> RilTempList(int idxDipendente, DateTime dtInizio, DateTime dtFine)
{
List<MaterialDTO>? dbResult = new List<MaterialDTO>();
List<RilievoTempModel>? dbResult = new List<RilievoTempModel>();
string currKey = $"{rKeyRilTemp}:{dtInizio:yyyyMMdd}:{dtFine:yyyMMdd}";
trackCache(currKey);
string rawData;
var redisDataList = await distributedCache.GetAsync(rKeyDipendenti);
var redisDataList = await distributedCache.GetAsync(currKey);
if (redisDataList != null)
{
rawData = Encoding.UTF8.GetString(redisDataList);
dbResult = JsonConvert.DeserializeObject<List<MaterialDTO>>(rawData);
dbResult = JsonConvert.DeserializeObject<List<RilievoTempModel>>(rawData);
}
else
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
dbResult = dbController.MaterialsGetAll();
dbResult = dbController.RilTempList(idxDipendente, dtInizio, dtFine);
rawData = JsonConvert.SerializeObject(dbResult, JSSettings);
redisDataList = Encoding.UTF8.GetBytes(rawData);
await distributedCache.SetAsync(rKeyDipendenti, redisDataList, cacheOpt(false));
await distributedCache.SetAsync(currKey, redisDataList, cacheOpt(true));
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Trace($"Effettuata lettura da DB + caching per GetMaterials: {ts.TotalMilliseconds} ms");
Log.Trace($"Effettuata lettura da DB + caching per RilTempList: {ts.TotalMilliseconds} ms");
}
if (dbResult == null)
{
dbResult = new List<MaterialDTO>();
dbResult = new List<RilievoTempModel>();
}
return await Task.FromResult(dbResult);
}
public async Task<List<MovMagModel>> MovMagGetFilt(int RemnId, int numShow)
{
List<MovMagModel> dbResult = new List<MovMagModel>();
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
dbResult = dbController.MovMagGetFilt(RemnId, numShow);
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Trace($"Effettuata lettura da DB + caching per MovMagGetFilt: {ts.TotalMilliseconds} ms");
return await Task.FromResult(dbResult);
}
public async Task<bool> AddPrintJob(int RemnId)
{
bool answ = dbController.AddPrintJob("docRemnant", $"{RemnId}", "queueRemnants");
return await Task.FromResult(answ);
}
public async Task<List<RemnantsModel>> RemnantsGetFilt(int matId, int minQty)
{
List<RemnantsModel>? dbResult = new List<RemnantsModel>();
string rawData;
string cacheKey = $"{rKeyRemnants}:{matId}:{minQty}";
if (!cachedDataList.Contains(cacheKey))
{
cachedDataList.Add(cacheKey);
}
var redisDataList = await distributedCache.GetAsync(cacheKey);
if (redisDataList != null)
{
rawData = Encoding.UTF8.GetString(redisDataList);
dbResult = JsonConvert.DeserializeObject<List<RemnantsModel>>(rawData);
}
else
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
var rawList = dbController.RemnantsGetFilt(matId, minQty);
dbResult = rawList.OrderBy(o => o.Area).ToList();
rawData = JsonConvert.SerializeObject(dbResult, JSSettings);
redisDataList = Encoding.UTF8.GetBytes(rawData);
await distributedCache.SetAsync(cacheKey, redisDataList, cacheOpt(false));
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Trace($"Effettuata lettura da DB + caching per RemnantsGetAll: {ts.TotalMilliseconds} ms");
}
if (dbResult == null)
{
dbResult = new List<RemnantsModel>();
}
return await Task.FromResult(dbResult);
}
public async Task<bool> RemnantsIsDupl(RemnantsModel currItem)
public async Task<bool> RilTempUpdate(RilievoTempModel currItem)
{
bool answ = false;
var rawList = dbController.RemnantsGetFilt(currItem.MatID, 0);
var duplicati = rawList
.Where(x => x.RemnID != currItem.RemnID && x.LMm == currItem.LMm && x.WMm == currItem.WMm && x.TMm == currItem.TMm)
.ToList();
answ = duplicati.Count > 0;
return await Task.FromResult(answ);
}
public async Task<bool> RemnantsMovMag(RemnantsModel currItem, string userId, int deltaQty)
{
bool done = false;
try
{
// recupero item da DB
var currRecord = dbController.RemnantGetByid(currItem.RemnID);
if (currRecord != null && currRecord.RemnID == currItem.RemnID)
{
// modifico qty entro limiti >=0..
if (currRecord.QtyAvail + deltaQty >= 0)
{
currRecord.QtyAvail = currRecord.QtyAvail + deltaQty;
done = dbController.RemnantsUpsert(currRecord, userId);
await InvalidateAllCache();
}
}
dbController.RilTempUpdate(currItem);
// invalido la cache...
await InvalidateCache(rKeyRilTemp);
//await InvalidateCache($"{rKeyWeekStats}:{currItem.IdxDipendente}");
await InvalidateCache($"{rKeyDailyData}:{currItem.IdxDipendente}");
answ = true;
}
catch (Exception exc)
{
Log.Error($"Eccezione in RemnantsMovMag:{Environment.NewLine}{exc}");
}
return await Task.FromResult(done);
catch
{ }
return answ;
}
public async Task<bool> RemnantsUpsert(RemnantsModel currItem, string userId)
{
bool done = false;
try
{
done = dbController.RemnantsUpsert(currItem, userId);
await InvalidateAllCache();
}
catch (Exception exc)
{
Log.Error($"Eccezione in RemnantsUpsert:{Environment.NewLine}{exc}");
}
return await Task.FromResult(done);
}
#endif
public void rollBackEdit(object item)
{
dbController.rollBackEntity(item);
}
#if false
public async Task<RemnantsModel> SearchQrRemnant(string QrCode)
{
RemnantsModel? answ = new RemnantsModel();
string rawData = "";
string cacheKey = $"{rKeyQrRemnants}:{QrCode}";
// cerco in redis
var redisData = await distributedCache.GetAsync(cacheKey);
if (redisData != null)
{
rawData = Encoding.UTF8.GetString(redisData);
answ = JsonConvert.DeserializeObject<RemnantsModel>(rawData);
}
// se non trovo cerco su DB
else
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
var foundItem = dbController.RemnantGetByQr(QrCode);
if (foundItem != null && foundItem.RemDtmx == QrCode)
{
rawData = JsonConvert.SerializeObject(foundItem, JSSettings);
redisData = Encoding.UTF8.GetBytes(rawData);
await distributedCache.SetAsync(cacheKey, redisData, cacheOpt(false));
answ = foundItem;
}
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Trace($"Effettuata lettura da DB + caching per SearchQrRemnant: {ts.TotalMilliseconds} ms");
}
if (answ == null)
{
answ = new RemnantsModel();
}
return await Task.FromResult(answ);
}
#endif
public async Task<bool> TimbratureDelete(TimbratureModel currItem)
{
bool answ = false;
+1 -1
View File
@@ -2,7 +2,7 @@
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Version>3.0.2201.1315</Version>
<Version>3.0.2201.1511</Version>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
+13 -3
View File
@@ -11,6 +11,16 @@
</div>
</dialog>
}
else if (showTemp)
{
<dialog class="modal fade show" tabindex="-1" style="display:block; background-color: rgba(10,10,10,.6);" aria-modal="true" role="dialog">
<div class="modal-dialog modal-xl">
<div class="modal-content">
<DayCheckEditor TargetDate="@DtRifTempRil" CloseReq="ResetDayCheck"></DayCheckEditor>
</div>
</div>
</dialog>
}
else if (currRecord != null)
{
<dialog class="modal fade show" tabindex="-1" style="display:block; background-color: rgba(10,10,10,.6);" aria-modal="true" role="dialog">
@@ -43,7 +53,7 @@ else if (ListTimbr != null)
</button>
</div>
<div class="btn-group w-100">
<button class="btn btn-sm btn-info py-0 @actionCss" @onclick="() => MoveWeek(-4)" title="-4 settimane" disabled="@isLoading">
<button class="btn btn-sm btn-outline-primary py-0 @actionCss" @onclick="() => MoveWeek(-4)" title="-4 settimane" disabled="@isLoading">
<div><sub>@currWeekSel.inizio.ToString("dd.MM.yy")</sub></div>
<i class="fas fa-angle-double-left"></i>
</button>
@@ -51,7 +61,7 @@ else if (ListTimbr != null)
<div>Week <b>@currWeekNum.ToString("00")</b></div>
<sub>@currYear</sub>
</button>
<button class="btn btn-sm btn-info py-0 @actionCss" @onclick="() => MoveWeek(4)" title="+4 settimane" disabled="@isLoading">
<button class="btn btn-sm btn-outline-primary py-0 @actionCss" @onclick="() => MoveWeek(4)" title="+4 settimane" disabled="@isLoading">
<div><sub>@currWeekSel.fine.ToString("dd.MM.yy")</sub></div>
<i class="fas fa-angle-double-right"></i>
</button>
@@ -91,7 +101,7 @@ else if (ListTimbr != null)
@foreach (var currItem in ListRecords)
{
<div class="col-12">
<DayHoriz DayDTO="@currItem" StartHour="@startHour" EndHour="@endHour" ListFasi="@ListFasi" ItemSelected="ReportSelect" ItemUpdated="UpdRegAttData" IdxDipSel="@IdxDipendente" PeriodSelected="PeriodoSelect"></DayHoriz>
<DayHoriz DayDTO="@currItem" StartHour="@startHour" EndHour="@endHour" ListFasi="@ListFasi" ItemSelected="ReportSelect" ItemUpdated="UpdRegAttData" IdxDipSel="@IdxDipendente" PeriodSelected="PeriodoSelect" ReqTempList="ShowTempRil"></DayHoriz>
</div>
}
</div>
+23
View File
@@ -26,6 +26,8 @@ namespace GPW.CORE.UI.Pages
private List<TimbratureModel> ListTimbr = null;
private bool selPeriod = false;
private List<WeekStatDTO> weekStatList = new List<WeekStatDTO>();
private bool showTemp = false;
private DateTime DtRifTempRil = DateTime.Today;
#endregion Private Fields
@@ -328,9 +330,19 @@ namespace GPW.CORE.UI.Pages
ListTimbr = newList;
}
/// <summary>
/// Indico item selezionato
/// </summary>
protected async void ShowTempRil(DateTime dataRif)
{
// salvo data
DtRifTempRil = dataRif;
showTemp = true;
}
protected async Task ReloadPeriodo()
{
selPeriod = false;
showTemp=false;
weekStatList = null;
currRecord = null;
ListTimbr = null;
@@ -365,6 +377,17 @@ namespace GPW.CORE.UI.Pages
protected async Task ResetSelPeriodo()
{
selPeriod = false;
showTemp = false;
currRecord = null;
ListTimbr = null;
await InitData(true);
await ReloadData();
}
protected async Task ResetDayCheck()
{
selPeriod = false;
showTemp = false;
currRecord = null;
ListTimbr = null;
await InitData(true);
+17 -6
View File
@@ -5,8 +5,19 @@
<PageTitle>Test - Fasi</PageTitle>
<div class="row">
<div class="col-4">
<ChartTS Id="TempRil" DataTS="@getTsData()" lineColor="rgb(7, 173, 236)" backColor="rgba(107, 223, 255, 0.3)"></ChartTS>
</div>
<div class="col-4">
<ChartHist Id="FreqTemp" Data="@(new[] { "5", "8", "10", "6", "4", "3" })" Labels="@(new[] { "35.8", "35.9", "36.0", "36.1", "36.2", "36.3" })" lineColor="rgb(7, 173, 236)" backColor="rgba(107, 223, 255, 0.5)"></ChartHist>
</div>
<div class="col-4">
<Chart Id="Bar" Type="@Chart.ChartType.Bar" Data="@(new[] { "10", "9", "12", "8", "14" })" BackgroundColor="@(new[] { "yellow","red", "green", "blue"})" Labels="@(new[] { "S01","S02","S03","S04"})"></Chart>
</div>
</div>
<div class="p-1 flex-fill text-left">
@*<div class="p-1 flex-fill text-left">
<div class="d-flex justify-content-between text-center">
<div class="py-0 small flex-fill " style="width: 5.36%"><div class="d-flex"><div class="px-1 small textTrim"><button class="px-1 text-center btn btn-lg btn-outline-success"><i class="fas fa-plus-circle"></i></button></div></div></div><div class="py-0 small flex-fill border border-info rounded" style="width: 3.57%">
<div class="d-flex">
@@ -279,7 +290,7 @@
</div>
</div><div class="py-0 small flex-fill " style="width: 5.36%"><div class="d-flex"><div class="px-1 small textTrim"><button class="px-1 text-center btn btn-lg btn-outline-success"><i class="fas fa-plus-circle"></i></button></div></div></div>
</div>
</div>
</div>*@
<style>
.containerTest {
@@ -301,10 +312,10 @@
z-index: 5;
}
.overlay:hover {
z-index: +100;
opacity: 1;
}
.overlay:hover {
z-index: +100;
opacity: 1;
}
</style>
+14
View File
@@ -96,6 +96,20 @@ namespace GPW.CORE.UI.Pages
}
}
protected List<chartJsData.chartJsTSerie> getTsData()
{
List<chartJsData.chartJsTSerie> answ = new List<chartJsData.chartJsTSerie>();
DateTime dtCurs = DateTime.Now.AddDays(-120);
Random rnd = new Random();
for (int i = 0; i < 60; i++)
{
answ.Add(new chartJsData.chartJsTSerie() { x = dtCurs, y = (decimal)(360 + rnd.Next(-5, 12)) / 10 });
dtCurs = dtCurs.AddDays(rnd.Next(1,4));
}
return answ;
}
#endregion Protected Properties
#region Private Methods
+4
View File
@@ -30,5 +30,9 @@
</div>
<script src="_framework/blazor.server.js"></script>
<script src="lib/Chart.js/chart.js"></script>
<script src="/lib/luxon/luxon.js"></script>
<script src="/lib/chartjs-adapter-luxon/chartjs-adapter-luxon.js"></script>
<script src="lib/chartBoot.js"></script>
</body>
</html>
+1
View File
@@ -8,3 +8,4 @@
@using Microsoft.JSInterop
@using GPW.CORE.UI
@using GPW.CORE.UI.Shared
@using GPW.CORE.UI.Components
+16
View File
@@ -0,0 +1,16 @@
namespace GPW.CORE.UI
{
public class chartJsData
{
public class chartJsTSerie
{
public DateTime x { get; set; }
public decimal y { get; set; }
}
public class chartJsXY
{
public decimal x { get; set; }
public decimal y { get; set; }
}
}
}
+17 -6
View File
@@ -5,11 +5,22 @@
{
"library": "font-awesome@5.15.4",
"destination": "wwwroot/lib/font-awesome/"
},
{
"library": "bootstrap@4.6.1",
"destination": "wwwroot/lib/bootstrap/"
},
{
"library": "Chart.js@3.7.0",
"destination": "wwwroot/lib/Chart.js/"
},
{
"library": "chartjs-adapter-luxon@1.1.0",
"destination": "wwwroot/lib/chartjs-adapter-luxon/"
},
{
"library": "luxon@2.3.0",
"destination": "wwwroot/lib/luxon/"
}
,
{
"library": "bootstrap@4.6.1",
"destination": "wwwroot/lib/bootstrap/"
}
]
]
}
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
@@ -0,0 +1,7 @@
/*!
* Chart.js v3.7.0
* https://www.chartjs.org
* (c) 2021 Chart.js Contributors
* Released under the MIT License
*/
export { H as HALF_PI, aX as INFINITY, P as PI, aW as PITAU, aZ as QUARTER_PI, aY as RAD_PER_DEG, T as TAU, a_ as TWO_THIRDS_PI, Q as _addGrace, V as _alignPixel, a0 as _alignStartEnd, p as _angleBetween, a$ as _angleDiff, _ as _arrayUnique, a6 as _attachContext, aq as _bezierCurveTo, an as _bezierInterpolation, av as _boundSegment, al as _boundSegments, a3 as _capitalize, ak as _computeSegments, a7 as _createResolver, aH as _decimalPlaces, aP as _deprecated, a8 as _descriptors, af as _elementsEqual, M as _factorize, aJ as _filterBetween, F as _getParentNode, U as _int16Range, ah as _isBetween, ag as _isClickEvent, K as _isDomSupported, z as _isPointInArea, w as _limitValue, aI as _longestText, aK as _lookup, x as _lookupByKey, S as _measureText, aN as _merger, aO as _mergerIf, aw as _normalizeAngle, ao as _pointInLine, ai as _readValueToProps, A as _rlookupByKey, aD as _setMinAndMaxByKey, am as _steppedInterpolation, ap as _steppedLineTo, az as _textX, $ as _toLeftRightCenter, aj as _updateBezierControlPoints, as as addRoundedRectPath, aG as almostEquals, aF as almostWhole, O as callback, ad as clearCanvas, W as clipArea, aM as clone, c as color, h as createContext, ab as debounce, j as defined, aC as distanceBetweenPoints, ar as drawPoint, D as each, e as easingEffects, N as finiteOrDefault, aU as fontString, o as formatNumber, B as getAngleFromPoint, aL as getHoverColor, E as getMaximumSize, y as getRelativePosition, ax as getRtlAdapter, aT as getStyle, b as isArray, g as isFinite, a5 as isFunction, k as isNullOrUndef, q as isNumber, i as isObject, l as listenArrayEvents, L as log10, a2 as merge, a9 as mergeIf, aE as niceNum, aB as noop, ay as overrideTextDirection, G as readUsedSize, X as renderText, r as requestAnimFrame, a as resolve, f as resolveObjectKey, aA as restoreTextDirection, ac as retinaScale, ae as setsEqual, s as sign, aR as splineCurve, aS as splineCurveMonotone, J as supportsEventListenerOptions, I as throttled, R as toDegrees, n as toDimension, Z as toFont, aQ as toFontString, aV as toLineHeight, C as toPadding, m as toPercentage, t as toRadians, at as toTRBL, au as toTRBLCorners, aa as uid, Y as unclipArea, u as unlistenArrayEvents, v as valueOrDefault } from './chunks/helpers.segment.js';
+1
View File
@@ -0,0 +1 @@
export{H as HALF_PI,aX as INFINITY,P as PI,aW as PITAU,aZ as QUARTER_PI,aY as RAD_PER_DEG,T as TAU,a_ as TWO_THIRDS_PI,Q as _addGrace,V as _alignPixel,a0 as _alignStartEnd,p as _angleBetween,a$ as _angleDiff,_ as _arrayUnique,a6 as _attachContext,aq as _bezierCurveTo,an as _bezierInterpolation,av as _boundSegment,al as _boundSegments,a3 as _capitalize,ak as _computeSegments,a7 as _createResolver,aH as _decimalPlaces,aP as _deprecated,a8 as _descriptors,af as _elementsEqual,M as _factorize,aJ as _filterBetween,F as _getParentNode,U as _int16Range,ah as _isBetween,ag as _isClickEvent,K as _isDomSupported,z as _isPointInArea,w as _limitValue,aI as _longestText,aK as _lookup,x as _lookupByKey,S as _measureText,aN as _merger,aO as _mergerIf,aw as _normalizeAngle,ao as _pointInLine,ai as _readValueToProps,A as _rlookupByKey,aD as _setMinAndMaxByKey,am as _steppedInterpolation,ap as _steppedLineTo,az as _textX,$ as _toLeftRightCenter,aj as _updateBezierControlPoints,as as addRoundedRectPath,aG as almostEquals,aF as almostWhole,O as callback,ad as clearCanvas,W as clipArea,aM as clone,c as color,h as createContext,ab as debounce,j as defined,aC as distanceBetweenPoints,ar as drawPoint,D as each,e as easingEffects,N as finiteOrDefault,aU as fontString,o as formatNumber,B as getAngleFromPoint,aL as getHoverColor,E as getMaximumSize,y as getRelativePosition,ax as getRtlAdapter,aT as getStyle,b as isArray,g as isFinite,a5 as isFunction,k as isNullOrUndef,q as isNumber,i as isObject,l as listenArrayEvents,L as log10,a2 as merge,a9 as mergeIf,aE as niceNum,aB as noop,ay as overrideTextDirection,G as readUsedSize,X as renderText,r as requestAnimFrame,a as resolve,f as resolveObjectKey,aA as restoreTextDirection,ac as retinaScale,ae as setsEqual,s as sign,aR as splineCurve,aS as splineCurveMonotone,J as supportsEventListenerOptions,I as throttled,R as toDegrees,n as toDimension,Z as toFont,aQ as toFontString,aV as toLineHeight,C as toPadding,m as toPercentage,t as toRadians,at as toTRBL,au as toTRBLCorners,aa as uid,Y as unclipArea,u as unlistenArrayEvents,v as valueOrDefault}from"./chunks/helpers.segment.js";
+17
View File
@@ -0,0 +1,17 @@

///Setup del chart desiderato con id univoco
window.setup = (id, config) => {
var ctx = document.getElementById(id).getContext('2d');
//let currentDate = new Date();
//console.log(currentDate + " - Calling setup...");
//console.log(id);
if (window['chart-' + id] instanceof Chart) {
//window.myChart.destroy();
window['chart-' + id].destroy();
//console.log("Chart " + id + " destroyed!");
}
window['chart-' + id] = new Chart(ctx, config);
//console.log("Chart " + id + " created!");
//console.log(window['chart-' + id]);
}
@@ -0,0 +1,91 @@
/*!
* chartjs-adapter-luxon v1.1.0
* https://www.chartjs.org
* (c) 2021 chartjs-adapter-luxon Contributors
* Released under the MIT license
*/
import { _adapters } from 'chart.js';
import { DateTime } from 'luxon';
const FORMATS = {
datetime: DateTime.DATETIME_MED_WITH_SECONDS,
millisecond: 'h:mm:ss.SSS a',
second: DateTime.TIME_WITH_SECONDS,
minute: DateTime.TIME_SIMPLE,
hour: {hour: 'numeric'},
day: {day: 'numeric', month: 'short'},
week: 'DD',
month: {month: 'short', year: 'numeric'},
quarter: "'Q'q - yyyy",
year: {year: 'numeric'}
};
_adapters._date.override({
_id: 'luxon', // DEBUG
/**
* @private
*/
_create: function(time) {
return DateTime.fromMillis(time, this.options);
},
formats: function() {
return FORMATS;
},
parse: function(value, format) {
const options = this.options;
if (value === null || typeof value === 'undefined') {
return null;
}
const type = typeof value;
if (type === 'number') {
value = this._create(value);
} else if (type === 'string') {
if (typeof format === 'string') {
value = DateTime.fromFormat(value, format, options);
} else {
value = DateTime.fromISO(value, options);
}
} else if (value instanceof Date) {
value = DateTime.fromJSDate(value, options);
} else if (type === 'object' && !(value instanceof DateTime)) {
value = DateTime.fromObject(value);
}
return value.isValid ? value.valueOf() : null;
},
format: function(time, format) {
const datetime = this._create(time);
return typeof format === 'string'
? datetime.toFormat(format, this.options)
: datetime.toLocaleString(format);
},
add: function(time, amount, unit) {
const args = {};
args[unit] = amount;
return this._create(time).plus(args).valueOf();
},
diff: function(max, min, unit) {
return this._create(max).diff(this._create(min)).as(unit).valueOf();
},
startOf: function(time, unit, weekday) {
if (unit === 'isoWeek') {
weekday = Math.trunc(Math.min(Math.max(0, weekday), 6));
const dateTime = this._create(time);
return dateTime.minus({days: (dateTime.weekday - weekday + 7) % 7}).startOf('day').valueOf();
}
return unit ? this._create(time).startOf(unit).valueOf() : time;
},
endOf: function(time, unit) {
return this._create(time).endOf(unit).valueOf();
}
});
@@ -0,0 +1 @@
import{_adapters}from"chart.js";import{DateTime}from"luxon";const FORMATS={datetime:DateTime.DATETIME_MED_WITH_SECONDS,millisecond:"h:mm:ss.SSS a",second:DateTime.TIME_WITH_SECONDS,minute:DateTime.TIME_SIMPLE,hour:{hour:"numeric"},day:{day:"numeric",month:"short"},week:"DD",month:{month:"short",year:"numeric"},quarter:"'Q'q - yyyy",year:{year:"numeric"}};_adapters._date.override({_id:"luxon",_create:function(t){return DateTime.fromMillis(t,this.options)},formats:function(){return FORMATS},parse:function(t,e){var r=this.options;if(null==t)return null;var a=typeof t;return"number"==a?t=this._create(t):"string"==a?t="string"==typeof e?DateTime.fromFormat(t,e,r):DateTime.fromISO(t,r):t instanceof Date?t=DateTime.fromJSDate(t,r):"object"!=a||t instanceof DateTime||(t=DateTime.fromObject(t)),t.isValid?t.valueOf():null},format:function(t,e){const r=this._create(t);return"string"==typeof e?r.toFormat(e,this.options):r.toLocaleString(e)},add:function(t,e,r){const a={};return a[r]=e,this._create(t).plus(a).valueOf()},diff:function(t,e,r){return this._create(t).diff(this._create(e)).as(r).valueOf()},startOf:function(t,e,r){if("isoWeek"!==e)return e?this._create(t).startOf(e).valueOf():t;{r=Math.trunc(Math.min(Math.max(0,r),6));const a=this._create(t);return a.minus({days:(a.weekday-r+7)%7}).startOf("day").valueOf()}},endOf:function(t,e){return this._create(t).endOf(e).valueOf()}});
@@ -0,0 +1,96 @@
/*!
* chartjs-adapter-luxon v1.1.0
* https://www.chartjs.org
* (c) 2021 chartjs-adapter-luxon Contributors
* Released under the MIT license
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('chart.js'), require('luxon')) :
typeof define === 'function' && define.amd ? define(['chart.js', 'luxon'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.Chart, global.luxon));
}(this, (function (chart_js, luxon) { 'use strict';
const FORMATS = {
datetime: luxon.DateTime.DATETIME_MED_WITH_SECONDS,
millisecond: 'h:mm:ss.SSS a',
second: luxon.DateTime.TIME_WITH_SECONDS,
minute: luxon.DateTime.TIME_SIMPLE,
hour: {hour: 'numeric'},
day: {day: 'numeric', month: 'short'},
week: 'DD',
month: {month: 'short', year: 'numeric'},
quarter: "'Q'q - yyyy",
year: {year: 'numeric'}
};
chart_js._adapters._date.override({
_id: 'luxon', // DEBUG
/**
* @private
*/
_create: function(time) {
return luxon.DateTime.fromMillis(time, this.options);
},
formats: function() {
return FORMATS;
},
parse: function(value, format) {
const options = this.options;
if (value === null || typeof value === 'undefined') {
return null;
}
const type = typeof value;
if (type === 'number') {
value = this._create(value);
} else if (type === 'string') {
if (typeof format === 'string') {
value = luxon.DateTime.fromFormat(value, format, options);
} else {
value = luxon.DateTime.fromISO(value, options);
}
} else if (value instanceof Date) {
value = luxon.DateTime.fromJSDate(value, options);
} else if (type === 'object' && !(value instanceof luxon.DateTime)) {
value = luxon.DateTime.fromObject(value);
}
return value.isValid ? value.valueOf() : null;
},
format: function(time, format) {
const datetime = this._create(time);
return typeof format === 'string'
? datetime.toFormat(format, this.options)
: datetime.toLocaleString(format);
},
add: function(time, amount, unit) {
const args = {};
args[unit] = amount;
return this._create(time).plus(args).valueOf();
},
diff: function(max, min, unit) {
return this._create(max).diff(this._create(min)).as(unit).valueOf();
},
startOf: function(time, unit, weekday) {
if (unit === 'isoWeek') {
weekday = Math.trunc(Math.min(Math.max(0, weekday), 6));
const dateTime = this._create(time);
return dateTime.minus({days: (dateTime.weekday - weekday + 7) % 7}).startOf('day').valueOf();
}
return unit ? this._create(time).startOf(unit).valueOf() : time;
},
endOf: function(time, unit) {
return this._create(time).endOf(unit).valueOf();
}
});
})));
@@ -0,0 +1,7 @@
/*!
* chartjs-adapter-luxon v1.1.0
* https://www.chartjs.org
* (c) 2021 chartjs-adapter-luxon Contributors
* Released under the MIT license
*/
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(require("chart.js"),require("luxon")):"function"==typeof define&&define.amd?define(["chart.js","luxon"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).Chart,e.luxon)}(this,(function(e,t){"use strict";const n={datetime:t.DateTime.DATETIME_MED_WITH_SECONDS,millisecond:"h:mm:ss.SSS a",second:t.DateTime.TIME_WITH_SECONDS,minute:t.DateTime.TIME_SIMPLE,hour:{hour:"numeric"},day:{day:"numeric",month:"short"},week:"DD",month:{month:"short",year:"numeric"},quarter:"'Q'q - yyyy",year:{year:"numeric"}};e._adapters._date.override({_id:"luxon",_create:function(e){return t.DateTime.fromMillis(e,this.options)},formats:function(){return n},parse:function(e,n){const r=this.options;if(null==e)return null;const i=typeof e;return"number"===i?e=this._create(e):"string"===i?e="string"==typeof n?t.DateTime.fromFormat(e,n,r):t.DateTime.fromISO(e,r):e instanceof Date?e=t.DateTime.fromJSDate(e,r):"object"!==i||e instanceof t.DateTime||(e=t.DateTime.fromObject(e)),e.isValid?e.valueOf():null},format:function(e,t){const n=this._create(e);return"string"==typeof t?n.toFormat(t,this.options):n.toLocaleString(t)},add:function(e,t,n){const r={};return r[n]=t,this._create(e).plus(r).valueOf()},diff:function(e,t,n){return this._create(e).diff(this._create(t)).as(n).valueOf()},startOf:function(e,t,n){if("isoWeek"===t){n=Math.trunc(Math.min(Math.max(0,n),6));const t=this._create(e);return t.minus({days:(t.weekday-n+7)%7}).startOf("day").valueOf()}return t?this._create(e).startOf(t).valueOf():e},endOf:function(e,t){return this._create(e).endOf(t).valueOf()}})}));
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1,6 +1,6 @@
<body>
<i>GPW - Gestione Presenze Web</i>
<h4>Versione: 3.0.2201.1315</h4>
<h4>Versione: 3.0.2201.1511</h4>
<br /> Note di rilascio:
<ul>
<li>
+1 -1
View File
@@ -1 +1 @@
3.0.2201.1315
3.0.2201.1511
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<item>
<version>3.0.2201.1315</version>
<version>3.0.2201.1511</version>
<url>http://nexus.steamware.net/repository/SWS/GWMS/stable/0/GWMS.UI.zip</url>
<changelog>http://nexus.steamware.net/repository/SWS/GWMS/stable/0/ChangeLog.html</changelog>
<mandatory>false</mandatory>