Compare commits

..

69 Commits

Author SHA1 Message Date
Samuele Locatelli 6d999f9eed Merge branch 'release/FixCICD' 2021-09-02 12:52:33 +02:00
Samuele Locatelli 9b4fa9f7f7 Refresh yaml gitalb x tag win 2021-09-02 12:52:01 +02:00
Samuele Locatelli 7785c4650e Merge tag 'ExportCsv' into develop
Completamento revisione export CSV
2021-07-02 19:20:43 +02:00
Samuele Locatelli 0e0269d8d7 Merge branch 'release/ExportCsv' 2021-07-02 19:20:20 +02:00
Samuele Locatelli 7864ec708d Merge branch 'feature/fixVisuals' into develop 2021-07-02 19:19:42 +02:00
Samuele Locatelli 355fa9e246 update note csv/xlsx + fix typo OEE 2021-07-02 19:19:36 +02:00
Samuele Locatelli e304c08e37 Refresh naming 2021-07-02 19:17:07 +02:00
Samuele Locatelli ed6d3d68f3 refresh gitignore 2021-07-02 19:07:00 +02:00
Samuele Locatelli a69100ad47 update gitignore 2021-07-02 19:06:25 +02:00
Samuele Locatelli 55b639c644 rimosso file 2021-07-02 19:06:18 +02:00
Samuele Locatelli 122b98a757 Ok gestione completa prime 2 pagine.. inizio refactor 2021-07-02 19:05:05 +02:00
Samuele Locatelli 595a09e0af Ok download anche del file x ODL 2021-07-02 18:56:40 +02:00
Samuele Locatelli ff2114a1e3 Bozza export data in CSV funzionante (da rivedere) 2021-07-02 18:23:18 +02:00
Samuele Locatelli e7c831d9a2 Fix scarti/rilav in ODL 2021-07-02 12:12:22 +02:00
Samuele Locatelli 54e62e59f0 Fix pagina OEE 2021-07-02 12:11:14 +02:00
Samuele Locatelli c35fd8b77e Merge branch 'develop' 2021-06-28 14:55:59 +02:00
Samuele Locatelli e9b18f8734 refresh vers 2021-06-28 14:55:53 +02:00
Samuele Locatelli 453ce2df39 Update modello QEE: calcolo durata turno variabile x calcolo OEE 2021-06-28 14:55:15 +02:00
Samuele Locatelli eecd7c2468 Merge branch 'develop' 2021-06-24 10:01:52 +02:00
Samuele Locatelli 8ac6ac5d17 Update filtro commesse con groupby 2021-06-24 10:01:26 +02:00
Samuele Locatelli d1be815f1f Update x fix filtraggio ODL --> v_UI_ODL 2021-06-24 09:42:12 +02:00
Samuele Locatelli b7f67488b2 Pulizia yaml install 2021-06-23 14:46:09 +02:00
Samuele Locatelli b5f5e1381a Merge tag 'FixDisplay_Durate_Articoli' into develop
Sistemate durate (display HH:mm:ss) + descrizione articoli
2021-06-23 13:16:54 +02:00
Samuele Locatelli 09822de144 Merge branch 'release/FixDisplay_Durate_Articoli' 2021-06-23 13:16:30 +02:00
Samuele Locatelli 13be2d8e40 refresh generalizzati 2021-06-23 13:15:38 +02:00
Samuele Locatelli e0505f4882 Omogenizzazione display pagine x durate, descr articolo, ... 2021-06-23 13:15:30 +02:00
Samuele Locatelli 45bf40496e metodi x calcolo hh-mm-ss da durate 2021-06-23 13:15:13 +02:00
Samuele Locatelli 9f8a452e40 Refresh modello dati x nuovi campi 2021-06-23 13:15:00 +02:00
Samuele Locatelli 27fd7d3b24 fix yaml 2021-06-21 18:28:46 +02:00
Samuele Locatelli eee46493c2 REFRESH 2021-06-21 18:20:30 +02:00
Samuele Locatelli 58823ab6ac Merge tag 'FixPagination' into develop
Inserita gestione paginazione per pagina DDB
2021-06-19 15:33:38 +02:00
Samuele Locatelli 8ab2255458 Merge branch 'release/FixPagination' 2021-06-19 15:33:14 +02:00
Samuele Locatelli 94190d0531 Merge branch 'feature/ReviewPaginazioneDDB' into develop 2021-06-19 14:35:12 +02:00
Samuele Locatelli fb92e08e53 Completata prima ottimizzazione caricamento dati paginato 2021-06-19 14:35:04 +02:00
Samuele Locatelli c8389f37b8 implementazione metodi paginati 2021-06-19 14:18:38 +02:00
Samuele Locatelli f1ddde0ff4 review struttura recupero dati da SQL paginati 2021-06-19 14:18:30 +02:00
Samuele Locatelli 560c0c400f start refresh 2021-06-19 14:18:13 +02:00
Samuele Locatelli 0e2a7907fa cambio parametro publish 2021-06-17 17:30:46 +02:00
Samuele Locatelli 15825cfb2d update path publish 2021-06-17 16:58:35 +02:00
Samuele Locatelli f40f9309a8 Merge branch 'develop' 2021-06-17 16:56:44 +02:00
Samuele Locatelli f81adbee29 provo modifiche x deploy su nexus 2021-06-17 16:56:16 +02:00
Samuele Locatelli d4c65cc8eb Merge remote-tracking branch 'origin/develop' into develop 2021-06-17 16:08:11 +02:00
Samuele Locatelli 2c50e8d762 nuovo ciclo yml da testare x MP-STATS su nexus 2021-06-17 16:07:41 +02:00
Samuele E. Locatelli ae655bebce Merge branch 'develop' 2021-06-15 18:57:52 +02:00
Samuele E. Locatelli d677d94cdc refresh 2021-06-15 18:57:45 +02:00
Samuele E. Locatelli c0f858335a Fix durata --> durata periodo 2021-06-15 18:57:40 +02:00
Samuele Locatelli f394827b10 fix inizio stato/inizio periodo 2021-06-15 10:43:50 +02:00
Samuele Locatelli 4652a92d42 update pagina dettaglio 2021-06-07 19:52:44 +02:00
Samuele Locatelli 3f5a8a0f05 Merge branch 'master' into develop 2021-06-03 10:32:54 +02:00
Samuele Locatelli 1fd7860e43 Fix init charts (si vedono da subito) 2021-06-03 10:32:42 +02:00
Samuele Locatelli efba20a614 Corrrezione yml 2021-05-27 14:34:53 +02:00
Samuele Locatelli 01ff6d7b32 Merge tag 'FullCiCd' into develop
Completata modifica CI/CD e testing x deploy su NEXUS
2021-05-27 14:32:41 +02:00
Samuele Locatelli 10e03c2c44 Merge branch 'release/FullCiCd' 2021-05-27 14:32:23 +02:00
Samuele Locatelli 4f31c0d62c Correzione path con "0" 2021-05-27 14:31:16 +02:00
Samuele Locatelli cfa522e6f8 Update default path x avere primo risultato 2021-05-27 13:32:04 +02:00
Samuele Locatelli 8fb10ea4d8 Update x pubblicazione su area _LATEST 2021-05-27 13:19:14 +02:00
Samuele Locatelli 8066f3b231 correzione x upload versioni storicizzate 2021-05-27 13:07:01 +02:00
Samuele Locatelli 4b4c2ac41c Update stage nexus upload 2021-05-27 12:49:56 +02:00
Samuele Locatelli f5bc1719db Altro test rilascio nexus 2021-05-27 12:29:18 +02:00
Samuele Locatelli 60780aa5c9 Modifica x copia ANCHE dei file x versione 2021-05-27 12:16:23 +02:00
Samuele Locatelli 57d9a0a6f7 fix filename (maybe) su nexus 2021-05-27 12:01:55 +02:00
Samuele Locatelli af0d71c915 Aggiunta copia foreach ricorsiva 2021-05-27 11:31:53 +02:00
Samuele Locatelli cb93b7a48f correzione fase pack + invio 2021-05-27 11:21:59 +02:00
Samuele Locatelli 36201de782 Cambio script pubblicazione zip package 2021-05-27 11:17:22 +02:00
Samuele Locatelli 551149f3d0 Modifica ciclo pubblicazione/zip/caricamento 2021-05-27 10:22:39 +02:00
Samuele Locatelli 732063abcb typo fix 2021-05-27 10:03:31 +02:00
Samuele Locatelli 788b865ccf Bozza gestione upload su nexus da provare 2021-05-27 09:58:34 +02:00
Samuele Locatelli 1b08de2be9 inizio bozza ultimo step (nexus) 2021-05-26 20:51:32 +02:00
Samuele Locatelli 05e15b6a9c Merge tag 'Vers_1.0' into develop
Versione Iniziale MP.STATS con CI/CD
2021-05-26 20:46:16 +02:00
49 changed files with 703 additions and 179 deletions
+6
View File
@@ -4,6 +4,12 @@
*.pdb
.vs/*
#--------------------------------
# area MP.Stats
#--------------------------------
/Mp.Stats/temp/*.csv
#--------------------------------
# Area VersGen
#--------------------------------
+80 -29
View File
@@ -4,8 +4,10 @@ variables:
# ASPNET_MERGE_PATH: 'C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools'
# EXE_RELEASE_FOLDER: 'c:\Projetcs\Compiled\GPW\Release'
# DEPLOY_FOLDER: 'c:\Projects\Deploy\GPW\Builds'
VERS_MAIN: '1.0'
NEW_REL: ''
# NEW_REL: ''
VERS_MAIN: '1.0'
NEXUS_PATH: 'MP-STATS'
APP_NAME: 'MP.Stats'
# helper x fix pacchetti nuget da repo locale nexus.steamware.net
.nuget-fix: &nuget-fix
@@ -18,17 +20,58 @@ variables:
}
echo $hasSource
# helper creazione hash files x IIS
.hashBuild: &hashBuild
- |
$Target = $env:APP_NAME + "\bin\publish\" + $env:APP_NAME + ".zip"
$MD5 = Get-FileHash $Target -Algorithm MD5
$SHA1 = Get-FileHash $Target -Algorithm SHA1
New-Item $Target".md5"
New-Item $Target".sha1"
$MD5.Hash | Set-Content -Path $Target".md5"
$SHA1.Hash | Set-Content -Path $Target".sha1"
echo "Created HASH files for $Target"
# helper x send su NEXUS x pack
.nexusUpload: &nexusUpload
- |
Set-Alias mCurl C:\Windows\system32\curl.exe
$currentDate = get-date -format yyMM;
$currentTime = get-date -format ddHH;
$VersNumb = Get-Content "Resources\VersNum.txt"
echo "Curr Version: $VersNumb"
if($CI_COMMIT_BRANCH -eq "master")
{
$version = "stable"
}
else
{
$version = "unstable"
}
$File2Send = Get-ChildItem($env:APP_NAME + "\bin\publish\*")
ForEach ($File in $File2Send) {
$FileName = Split-Path $File -leaf
mCurl -v -u GitLab:$NEXUS_PASSWD --upload-file $File http://nexus.steamware.net/repository/SWS/$env:NEXUS_PATH/$version/0/$FileName
mCurl -v -u GitLab:$NEXUS_PASSWD --upload-file $File http://nexus.steamware.net/repository/SWS/$env:NEXUS_PATH/$version/$VersNumb/$FileName
}
mCurl -v -u GitLab:$NEXUS_PASSWD --upload-file "Resources\manifest.xml" http://nexus.steamware.net/repository/SWS/$env:NEXUS_PATH/$version/0/manifest.xml
mCurl -v -u GitLab:$NEXUS_PASSWD --upload-file "Resources\ChangeLog.html" http://nexus.steamware.net/repository/SWS/$env:NEXUS_PATH/$version/0/ChangeLog.html
# mCurl -v -u $env:NEXUS_USER:$env:NEXUS_PASSWD --upload-file bin/release/$env:APP_NAME.zip $env:NEXUS_SERVER/utility/$env:NEXUS_PATH/$version/$env:APP_NAME-$version.zip
stages:
- build
- test
- staging
- deploy
- release
- installer
- release
build:
stage: build
tags:
- win
before_script:
- *nuget-fix
- dotnet restore
@@ -37,17 +80,21 @@ build:
test:
stage: test
tags:
- win
only:
- develop
needs: ["build"]
script:
- dotnet test
staging:
stage: staging
IIS01:deploy:
stage: deploy
tags:
- win
only:
- develop
needs: ["build"]
needs: ["test"]
# before_script:
# - *nuget-fix
# - dotnet restore
@@ -55,8 +102,10 @@ staging:
- dotnet publish -p:PublishProfile=IIS01.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=viadante16 -p:AllowUntrustedCertificate=true MP.Stats/MP.Stats.csproj
staging:
IIS02:deploy:
stage: deploy
tags:
- win
only:
- master
needs: ["build"]
@@ -67,11 +116,33 @@ staging:
- dotnet publish -p:PublishProfile=IIS02.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=viadante16 -p:AllowUntrustedCertificate=true MP.Stats/MP.Stats.csproj
- dotnet publish -p:PublishProfile=W2019-IIS-DEVProfile.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=viadante16 -p:AllowUntrustedCertificate=true MP.Stats/MP.Stats.csproj
installer:
stage: installer
tags:
- win
only:
- develop
- master
needs: ["build"]
before_script:
# - *nuget-fix
# - dotnet restore
script:
- dotnet publish -p:PublishProfile=IISProfile.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release MP.Stats/MP.Stats.csproj -o:publish
# qui il deploy su nexus...
- *hashBuild
- *nexusUpload
release:
stage: release
tags:
- win
only:
#- feature/Deploy_CI_CD
- master
# - master
- tags
except:
- branches
needs: ["build"]
artifacts:
paths:
@@ -80,23 +151,3 @@ release:
- dotnet publish -c Release -o ./publish MP.Stats/MP.Stats.csproj
# AC:install:
# stage: installer
# rules:
# - if: '$CI_COMMIT_BRANCH == "master"'
# when: manual
# # only:
# # - tags # the build process will only be started by git tag commits
# before_script:
# - *nuget-fix
# - '& "$env:NUGET_PATH" restore GPW.sln'
# - *version-fix
# script:
# # Admin ZIP package
# - '& "$env:MSBUILD_PATH" /p:m=8 /p:AspnetMergePath=$env:ASPNET_MERGE_PATH /T:Package /P:Configuration=SPS /p:PublishProfile=SPS.pubxml /p:RunCodeAnalysis=false /p:PackageLocation=ReleaseClienti/SPS_PROD/$env:NEW_REL/GPW_Admin.zip /p:DeployIisAppPath="Default Web Site/GPW/ADMIN" /p:PackageAsSingleFile=True /p:OutputPath=bin/ GPW_Admin/GPW_Admin.csproj'
# # Commesse ZIP package
# - '& "$env:MSBUILD_PATH" /p:m=8 /p:AspnetMergePath=$env:ASPNET_MERGE_PATH /T:Package /P:Configuration=SPS /p:PublishProfile=SPS.pubxml /p:RunCodeAnalysis=false /p:PackageLocation=ReleaseClienti/SPS_PROD/$env:NEW_REL/GPW_Commesse.zip /p:DeployIisAppPath="Default Web Site/GPW/ADMIN" /p:PackageAsSingleFile=True /p:OutputPath=bin/ GPW_Commesse/GPW_Commesse.csproj'
# needs: ["AC:build"]
+32 -4
View File
@@ -167,10 +167,16 @@ namespace MP.Data.Controllers
/// <summary>
/// Elenco tabella DDB da filtro
/// </summary>
/// <param name="numRecord"></param>
/// <param name="searchVal"></param>
/// <param name="DataStart"></param>
/// <param name="DataEnd"></param>
/// <param name="IdxMacchina"></param>
/// <param name="IdxODL"></param>
/// <param name="KeyRichiesta"></param>
/// <param name="CodArticolo"></param>
/// <param name="FirstRecord"></param>
/// <param name="NumRecord"></param>
/// <returns></returns>
public List<DatabaseModels.DdbTurni> StatDdbGetAll(DateTime DataStart, DateTime DataEnd, string IdxMacchina, int IdxODL, string KeyRichiesta, string CodArticolo)
public List<DatabaseModels.DdbTurni> StatDdbGetAll(DateTime DataStart, DateTime DataEnd, string IdxMacchina, int IdxODL, string KeyRichiesta, string CodArticolo, int FirstRecord, int NumRecord)
{
List<DatabaseModels.DdbTurni> dbResult = new List<DatabaseModels.DdbTurni>();
@@ -180,15 +186,37 @@ namespace MP.Data.Controllers
var idxODL = new SqlParameter("@IdxODL", IdxODL);
var keyRichiesta = new SqlParameter("@KeyRichiesta", KeyRichiesta);
var codArticolo = new SqlParameter("@CodArticolo", CodArticolo);
var firstRecord = new SqlParameter("@FirstRecord", FirstRecord);
var numRecord = new SqlParameter("@NumRecord", NumRecord);
dbResult = dbCtx
.DbSetDdbTurni
.FromSqlRaw("EXEC stp_UI_DDBTurni_GetByFilter @dataFrom,@dataTo,@idxMacchina,@IdxODL,@KeyRichiesta,@CodArticolo", dataFrom, dataTo, idxMacchina, idxODL, keyRichiesta, codArticolo)
.FromSqlRaw("EXEC stp_UI_DDBTurni_GetByFilter @dataFrom,@dataTo,@idxMacchina,@IdxODL,@KeyRichiesta,@CodArticolo,@FirstRecord,@NumRecord", dataFrom, dataTo, idxMacchina, idxODL, keyRichiesta, codArticolo, firstRecord, numRecord)
.ToList();
return dbResult;
}
/// <summary>
/// Elenco tabella DDB da filtro
/// </summary>
/// <param name="DataStart"></param>
/// <param name="DataEnd"></param>
/// <param name="IdxMacchina"></param>
/// <param name="IdxODL"></param>
/// <param name="KeyRichiesta"></param>
/// <param name="CodArticolo"></param>
/// <returns></returns>
public int StatDdbGetCount(DateTime DataStart, DateTime DataEnd, string IdxMacchina, int IdxODL, string KeyRichiesta, string CodArticolo)
{
var dbResult = dbCtx
.DbSetDdbTurni
.Where(x => (x.IdxMacchina == IdxMacchina || IdxMacchina == "*") && (x.IdxOdl == IdxODL || IdxODL == -999) && (x.KeyRichiesta == KeyRichiesta || KeyRichiesta == "*") && (x.CodArticolo == CodArticolo || CodArticolo == "*") && (x.InizioPeriodo >= DataStart && x.InizioPeriodo <= DataEnd))
.Count();
return dbResult;
}
/// <summary>
/// Elenco tabella ODL da filtro
/// </summary>
+1
View File
@@ -17,6 +17,7 @@ namespace MP.Data.DatabaseModels
public DateTime DataRif { get; set; }
public DateTime? DataTurnoFine { get; set; }
public DateTime? DataTurnoInizio { get; set; }
public string DescArticolo { get; set; } = "";
public string Descrizione { get; set; }
[NotMapped]
+2 -1
View File
@@ -9,10 +9,11 @@ namespace MP.Data.DatabaseModels
{
#region Public Properties
public string CodArticolo { get; set; }
public string CodArticolo { get; set; } = "";
public string CodArticoloParent { get; set; }
public DateTime? DataFine { get; set; }
public DateTime? DataInizio { get; set; }
public string DescArticolo { get; set; } = "";
public DateTime? DueDate { get; set; }
public string IdxMacchina { get; set; }
public int IdxOdl { get; set; }
+5
View File
@@ -10,12 +10,17 @@ namespace MP.Data.DatabaseModels
#region Public Properties
public string CodArticolo { get; set; }
public string CodMacchina { get; set; } = "";
public string Cognome { get; set; } = "";
public DateTime DataOra { get; set; }
public string DescArticolo { get; set; } = "";
public bool EsitoOk { get; set; }
public int IdxControllo { get; set; }
public string IdxMacchina { get; set; }
public int IdxOdl { get; set; }
public string KeyRichiesta { get; set; }
public int MatrOpr { get; set; }
public string Nome { get; set; } = "";
public string Note { get; set; }
#endregion Public Properties
+1
View File
@@ -14,6 +14,7 @@ namespace MP.Data.DatabaseModels
public string CodMacchina { get; set; }
public string Cognome { get; set; }
public DateTime DataOraRif { get; set; }
public string DescArticolo { get; set; } = "";
public string Descrizione { get; set; }
public string IdxMacchina { get; set; }
public int IdxOdl { get; set; }
+4 -1
View File
@@ -20,12 +20,15 @@ namespace MP.Data.DatabaseModels
[NotMapped]
[DisplayFormat(DataFormatString = "{0:N2}", ApplyFormatInEditMode = true)]
public double OEE => (double)TotPeriodo / 480;
public double OEE => (double)TotPeriodo / (double)TotTurno;
[DisplayFormat(DataFormatString = "{0:N2}", ApplyFormatInEditMode = true)]
public decimal TotPeriodo { get; set; }
public int? TotPz { get; set; }
public int? TotTurno { get; set; } = 1;
public string Turno { get; set; }
#endregion Public Properties
+1
View File
@@ -14,6 +14,7 @@ namespace MP.Data.DatabaseModels
public string CodMacchina { get; set; }
public string Cognome { get; set; }
public DateTime DataOraRif { get; set; }
public string DescArticolo { get; set; } = "";
public int IdxLog { get; set; }
public string IdxMacchina { get; set; }
public int IdxOdl { get; set; }
+3 -4
View File
@@ -26,8 +26,7 @@ namespace MP.Data
_configuration = configuration;
}
public MoonPro_STATSContext(DbContextOptions<MoonPro_STATSContext> options)
: base(options)
public MoonPro_STATSContext(DbContextOptions<MoonPro_STATSContext> options) : base(options)
{
}
@@ -65,7 +64,7 @@ namespace MP.Data
{
string connString = _configuration.GetConnectionString("Mp.Stats");
optionsBuilder.UseSqlServer(_configuration.GetConnectionString("Mp.Stats"));
optionsBuilder.UseSqlServer(connString);
//optionsBuilder.UseSqlServer("Server=SQL2016DEV;Database=MoonPro_STATS;Trusted_Connection=True;");
}
}
@@ -334,7 +333,7 @@ namespace MP.Data
entity.HasKey(e => e.IdxOdl)
.HasName("PK_ODL_1");
entity.ToTable("ODL");
entity.ToTable("v_UI_ODL");
entity.Property(e => e.IdxOdl)
.ValueGeneratedNever()
+1 -1
View File
@@ -1,7 +1,7 @@
# Appunti gestione MP-STAT DB
Per la gestione dell'accesso al DB statistiche si opera con EFCore --> apop blazor server
Per la gestione dell'accesso al DB statistiche si opera con EFCore --> app blazor server
## Scaffolding
+44
View File
@@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MP.Data
{
public class Utils
{
#region Public Methods
public static string ConvMinToTime(double minutes)
{
// FIXME TODO: da rendere parametrico da appsettings.json...
var ts = TimeSpan.FromMinutes(minutes);
string answ = $"{ts.Hours:00}:{ts.Minutes:00}:{ts.Seconds:00}"; //.{ts.Milliseconds}
return answ;
}
public static string ConvMsecToTime(long milliseconds)
{
// FIXME TODO: da rendere parametrico da appsettings.json...
var ts = TimeSpan.FromMilliseconds(milliseconds);
string answ = $"{ts.Hours:00}:{ts.Minutes:00}:{ts.Seconds:00}"; //.{ts.Milliseconds}
return answ;
}
public static async Task SaveToCsv<T>(List<T> reportData, string path)
{
var lines = new List<string>();
IEnumerable<PropertyDescriptor> props = TypeDescriptor.GetProperties(typeof(T)).OfType<PropertyDescriptor>();
var header = string.Join(";", props.ToList().Select(x => x.Name));
lines.Add(header);
var valueLines = reportData.Select(row => string.Join(";", header.Split(';').Select(a => row.GetType().GetProperty(a).GetValue(row, null))));
lines.AddRange(valueLines);
await Task.Run(() => File.WriteAllLines(path, lines.ToArray()));
}
#endregion Public Methods
}
}
+2 -2
View File
@@ -85,8 +85,8 @@ namespace MP.Stats.Components
AspectRatio = 1
};
protected PieChart<double> PieVC;
protected LineChart<double> TimeSerieVC;
protected PieChart<double> PieVC = new PieChart<double>();
protected LineChart<double> TimeSerieVC = new LineChart<double>();
#endregion Protected Fields
+1 -1
View File
@@ -13,7 +13,7 @@
{
<li class="list-group-item p-1 d-flex justify-content-between align-items-center">
@item.label
<span class="badge badge-primary badge-pill">@item.value.ToString("P1")</span>
<span class="badge badge-primary badge-pill">@item.value.ToString("N2")%</span>
</li>
}
</ul>
+7 -6
View File
@@ -62,10 +62,11 @@ namespace MP.Stats.Components
new {
Display = true,
ticks= new {
suggestedMin = 0
min = 0,
max = 100
}
}
}
}
},
Tooltips = new
{
@@ -81,9 +82,9 @@ namespace MP.Stats.Components
AspectRatio = 3.5
};
protected LineChart<double> NumGuasti;
protected LineChart<double> NumGuasti = new LineChart<double>();
protected BarChart<double> ParetoGuasti;
protected BarChart<double> ParetoGuasti = new BarChart<double>();
#endregion Protected Fields
@@ -177,13 +178,13 @@ namespace MP.Stats.Components
{
ParetoData = RawData
.GroupBy(x => x.IdxMacchina)
.Select(y => new ChartKV() { label = y.First().IdxMacchina, value = y.Average(c => c.OEE) })
.Select(y => new ChartKV() { label = y.First().CodMacchina, value = Math.Round(y.Average(c => c.OEE) * 100, 2) })
.OrderByDescending(x => x.value)
.ToList();
TSData = RawData
.GroupBy(x => x.DataRif.Date)
.Select(y => new ChartTS() { TLabel = y.First().DataRif.Date, Value = y.Average(c => c.OEE) })
.Select(y => new ChartTS() { TLabel = y.First().DataRif.Date, Value = Math.Round(y.Average(c => c.OEE) * 100, 2) })
.OrderBy(x => x.TLabel)
.ToList();
}
+2 -2
View File
@@ -81,9 +81,9 @@ namespace MP.Stats.Components
AspectRatio = 3.5
};
protected LineChart<double> NumGuasti;
protected LineChart<double> NumGuasti = new LineChart<double>();
protected BarChart<double> ParetoGuasti;
protected BarChart<double> ParetoGuasti = new BarChart<double>();
#endregion Protected Fields
+2 -2
View File
@@ -85,8 +85,8 @@ namespace MP.Stats.Components
AspectRatio = 1
};
protected PieChart<double> PieVC;
protected LineChart<double> TimeSerieVC;
protected PieChart<double> PieVC = new PieChart<double>();
protected LineChart<double> TimeSerieVC = new LineChart<double>();
#endregion Protected Fields
+54 -43
View File
@@ -4,43 +4,54 @@
<div class="col-9 small">
@if (totalCount > 0)
{
<Pagination>
<PaginationItem>
<PaginationLink Clicked="@HandlePaginationItemClick" Page="1">
<i class="fas fa-angle-double-left"></i>
</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationLink Clicked="@HandlePaginationItemClick" Page="@prevBlock.ToString()">
<span aria-hidden="true"><i class="fas fa-angle-left"></i></span>
</PaginationLink>
</PaginationItem>
@for (int i = @startPage; i <= endPage; ++i)
<Pagination>
<PaginationItem>
<PaginationLink Clicked="@HandlePaginationItemClick" Page="1">
<i class="fas fa-angle-double-left"></i>
</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationLink Clicked="@HandlePaginationItemClick" Page="@prevBlock.ToString()">
<span aria-hidden="true"><i class="fas fa-angle-left"></i></span>
</PaginationLink>
</PaginationItem>
@for (int i = @startPage; i <= endPage; ++i)
{
var pageNum = i;
<PaginationItem Active="@(currPage.Equals(pageNum))">
<PaginationLink Clicked="@HandlePaginationItemClick" Page="@pageNum.ToString()">
@pageNum
</PaginationLink>
</PaginationItem>
<PaginationItem Active="@(currPage.Equals(pageNum))">
<PaginationLink Clicked="@HandlePaginationItemClick" Page="@pageNum.ToString()">
@pageNum
</PaginationLink>
</PaginationItem>
}
<PaginationItem>
<PaginationLink Clicked="@HandlePaginationItemClick" Page="@nextBlock.ToString()">
<i class="fas fa-angle-right"></i>
</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationLink Clicked="@HandlePaginationItemClick" Page="@LastPage.ToString()">
<i class="fas fa-angle-double-right"></i>
</PaginationLink>
</PaginationItem>
</Pagination>
<PaginationItem>
<PaginationLink Clicked="@HandlePaginationItemClick" Page="@nextBlock.ToString()">
<i class="fas fa-angle-right"></i>
</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationLink Clicked="@HandlePaginationItemClick" Page="@LastPage.ToString()">
<i class="fas fa-angle-double-right"></i>
</PaginationLink>
</PaginationItem>
</Pagination>
}
</div>
<div class="col-3">
<div class="col-3 text-center">
@if (!showLoading)
{
<span>@totalCount records</span>
<div>@totalCount records</div>
}
@if (totalCount > 0)
{
if (!fileExist)
{
<button class="btn btn-block btn-sm btn-primary" @onclick="() => requestSave()"><span class="oi oi-wrench"></span> Prepare Data</button>
}
else
{
<a target="_blank" href="/Download?fileName=@fileName" class="btn btn-block btn-sm btn-success"><span class="oi oi-cloud-download"></span> Download Data</a>
}
}
</div>
</div>
@@ -48,9 +59,9 @@
<div class="col-12 small">
@if (showLoading)
{
<Progress>
<ProgressBar Value="@percLoading" Striped="true" Animated="true" />
</Progress>
<Progress>
<ProgressBar Value="@percLoading" Striped="true" Animated="true" />
</Progress>
}
</div>
</div>
@@ -58,16 +69,16 @@
<div class="col-6 col-lg-2 text-right">
@if (totalCount > 0)
{
<div class="input-group input-group-sm">
row/pag:&nbsp;
<select @bind="@PageSize" class="form-control form-control-sm">
<option value="5">5</option>
<option value="10">10</option>
<option value="25">25</option>
<option value="50">50</option>
<option value="100">100</option>
</select>
</div>
<div class="input-group input-group-sm">
row/pag:&nbsp;
<select @bind="@PageSize" class="form-control form-control-sm">
<option value="5">5</option>
<option value="10">10</option>
<option value="25">25</option>
<option value="50">50</option>
<option value="100">100</option>
</select>
</div>
}
</div>
</div>
+29
View File
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
@@ -14,6 +15,8 @@ namespace MP.Stats.Components
protected bool _showLoading = false;
protected string exportDir = $"{Directory.GetCurrentDirectory()}/temp";
#endregion Protected Fields
#region Private Properties
@@ -80,6 +83,19 @@ namespace MP.Stats.Components
protected int _numRecord { get; set; } = 10;
protected bool fileExist
{
get
{
return File.Exists(fullPath);
}
}
protected string fullPath
{
get => $"{exportDir}/{fileName}";
}
protected int percLoading { get; set; } = 0;
#endregion Protected Properties
@@ -104,6 +120,12 @@ namespace MP.Stats.Components
}
}
[Parameter]
public EventCallback<int> exportRequested { get; set; }
[Parameter]
public string fileName { get; set; }
[Parameter]
public EventCallback<int> numPageChanged { get; set; }
@@ -167,6 +189,13 @@ namespace MP.Stats.Components
numPageChanged.InvokeAsync(currPage);
}
private async Task requestSave()
{
showLoading = true;
await exportRequested.InvokeAsync(currPage);
showLoading = false;
}
#endregion Private Methods
#region Protected Methods
+1 -1
View File
@@ -1,4 +1,4 @@
<div class="row py-5 my-5">
<div class="row p-5 m-5">
<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>
+43 -3
View File
@@ -91,6 +91,14 @@ namespace MP.Stats.Data
}
}
private DistributedCacheEntryOptions cacheOptLong
{
get
{
return new DistributedCacheEntryOptions().SetAbsoluteExpiration(DateTime.Now.AddMinutes(chAbsExp * 10)).SetSlidingExpiration(TimeSpan.FromMinutes(chSliExp));
}
}
#endregion Private Properties
#region Protected Methods
@@ -101,6 +109,12 @@ namespace MP.Stats.Data
return answ;
}
protected string getCacheKeyPaged(string TableName, SelectData CurrFilter)
{
string answ = $"{TableName}:M_{CurrFilter.IdxMacchina}:A_{CurrFilter.CodArticolo}:K_{CurrFilter.KeyRichiesta}:O_{CurrFilter.IdxOdl}:D_{CurrFilter.DateStart:yyMMddHHmm}_{CurrFilter.DateEnd:yyMMddHHmm}:R_{CurrFilter.FirstRecord}_{CurrFilter.FirstRecord + CurrFilter.NumRecord}";
return answ;
}
#endregion Protected Methods
#region Public Methods
@@ -158,7 +172,7 @@ namespace MP.Stats.Data
answ.Add(new AutocompleteModel { LabelField = "--- TUTTE ---", ValueField = "*" });
if (numRecord > -1)
{
answ.AddRange(dbController.CommesseGetSearch(numRecord, searchVal).Select(x => new AutocompleteModel { LabelField = $"{x.CodArticolo} | {x.KeyRichiesta}", ValueField = x.KeyRichiesta }).ToList());
answ.AddRange(dbController.CommesseGetSearch(numRecord, searchVal).GroupBy(x => x.KeyRichiesta).Select(x => new AutocompleteModel { LabelField = $"{x.First().CodArticolo} | {x.First().KeyRichiesta}", ValueField = x.First().KeyRichiesta }).ToList());
}
return Task.FromResult(answ);
}
@@ -212,7 +226,7 @@ namespace MP.Stats.Data
{
//return Task.FromResult(dbController.StatDdbGetAll(numRecord, searchVal).ToArray());
List<MP.Data.DatabaseModels.DdbTurni> dbResult = new List<MP.Data.DatabaseModels.DdbTurni>();
string cacheKey = getCacheKey("MP:STATS:DDBT", CurrFilter);
string cacheKey = getCacheKeyPaged("MP:STATS:DDBT", CurrFilter);
string rawData;
var redisDataList = await distributedCache.GetAsync(cacheKey);
if (redisDataList != null)
@@ -224,7 +238,7 @@ namespace MP.Stats.Data
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
dbResult = dbController.StatDdbGetAll(CurrFilter.DateStart, CurrFilter.DateEnd, CurrFilter.IdxMacchina, CurrFilter.IdxOdl, CurrFilter.KeyRichiesta, CurrFilter.CodArticolo);
dbResult = dbController.StatDdbGetAll(CurrFilter.DateStart, CurrFilter.DateEnd, CurrFilter.IdxMacchina, CurrFilter.IdxOdl, CurrFilter.KeyRichiesta, CurrFilter.CodArticolo, CurrFilter.FirstRecord, CurrFilter.NumRecord);
rawData = JsonConvert.SerializeObject(dbResult);
redisDataList = Encoding.UTF8.GetBytes(rawData);
await distributedCache.SetAsync(cacheKey, redisDataList, cacheOpt);
@@ -235,6 +249,32 @@ namespace MP.Stats.Data
return await Task.FromResult(dbResult);
}
public async Task<int> StatDdbGetCount(SelectData CurrFilter, string searchVal = "")
{
int numRec = 0;
string cacheKey = getCacheKey("MP:STATS:DDBT-COUNT", CurrFilter);
string rawData;
var redisDataList = await distributedCache.GetAsync(cacheKey);
if (redisDataList != null)
{
rawData = Encoding.UTF8.GetString(redisDataList);
int.TryParse(rawData, out numRec);
}
else
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
numRec = dbController.StatDdbGetCount(CurrFilter.DateStart, CurrFilter.DateEnd, CurrFilter.IdxMacchina, CurrFilter.IdxOdl, CurrFilter.KeyRichiesta, CurrFilter.CodArticolo);
rawData = $"{numRec}";
redisDataList = Encoding.UTF8.GetBytes(rawData);
await distributedCache.SetAsync(cacheKey, redisDataList, cacheOptLong);
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Info($"Effettuata lettura da DB + caching per DdbTurni: {ts.TotalMilliseconds} ms");
}
return await Task.FromResult(numRec);
}
public async Task<List<MP.Data.DatabaseModels.ODL>> StatOdlGetAll(SelectData CurrFilter, string searchVal = "")
{
//return Task.FromResult(dbController.StatOdlGetAll(numRecord, searchVal));
+32
View File
@@ -12,10 +12,38 @@ namespace MP.Stats.Data
public string CodArticolo { get; set; } = "*";
public DateTime DateEnd { get; set; } = DateTime.Now.AddMinutes(1);
public DateTime DateStart { get; set; } = DateTime.Now.AddDays(-7);
/// <summary>
/// Primo record x selezione paginata, tipicamente primo della "decina" della pagina corrente
/// </summary>
public int FirstRecord
{
get
{
int primaPag = PageNum % 10;
int decina = PageNum - primaPag;
return PageSize * decina + 1;
}
}
public string IdxMacchina { get; set; } = "*";
public int IdxOdl { get; set; } = -999;
public string KeyRichiesta { get; set; } = "*";
/// <summary>
/// Numero record da recuperare, tipicamente la decina della pag corrente (10 * PageSize)
/// </summary>
public int NumRecord
{
get
{
return PageSize * 10;
}
}
public int PageNum { get; set; } = 1;
public int PageSize { get; set; } = 10;
#endregion Public Properties
#region Public Methods
@@ -44,6 +72,10 @@ namespace MP.Stats.Data
if (!(obj is SelectData item))
return false;
if (PageSize != item.PageSize)
return false;
if (PageNum != item.PageNum)
return false;
if (CodArticolo != item.CodArticolo)
return false;
if (DateEnd != item.DateEnd)
+4 -1
View File
@@ -4,7 +4,7 @@
<TargetFramework>net5.0</TargetFramework>
<RootNamespace>MP.Stats</RootNamespace>
<UserSecretsId>826e877c-ba70-4253-84cb-d0b1cafd4440</UserSecretsId>
<Version>1.0.2105.2620</Version>
<Version>1.0.2107.0219</Version>
</PropertyGroup>
<ItemGroup>
@@ -47,6 +47,9 @@
<None Update="logs\.placeholder">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="temp\.placeholder">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="powershell.exe -ExecutionPolicy Unrestricted -NoProfile -NonInteractive -File $(ProjectDir)\post-build.ps1 -ProjectDir $(ProjectDir) -ProjectPath $(ProjectPath)" />
+19 -7
View File
@@ -1,4 +1,4 @@
@page "/controlli"
@page "/Controlli"
@*@page "/controlli/{IdxMacchina}"*@
@using MP.Stats.Components
@@ -29,7 +29,7 @@
<tr>
<th>Macchina</th>
<th>Data</th>
<th>ODL/Commessa</th>
<th>Commessa/ODL</th>
<th>Articolo</th>
<th>Esito</th>
<th>Note</th>
@@ -40,13 +40,25 @@
@foreach (var record in ListRecords)
{
<tr class="@checkSelect(@record.IdxControllo)">
<td>@record.IdxMacchina</td>
<td>@record.DataOra</td>
<td>@record.IdxOdl</td>
<td>@record.CodArticolo</td>
<td>
<div>@record.CodMacchina</div>
<div class="small">@record.IdxMacchina</div>
</td>
<td>
<div>@record.DataOra.ToString("yyyy.MM.dd")</div>
<div class="small">@record.DataOra.ToString("ddd HH:mm.ss")</div>
</td>
<td>
<div>@record.KeyRichiesta</div>
<div class="small">@record.IdxOdl</div>
</td>
<td>
@record.CodArticolo
<div class="small">@record.DescArticolo</div>
</td>
<td>@record.EsitoOk</td>
<td>@record.Note</td>
<td>@record.MatrOpr</td>
<td class="text-right">@record.Cognome @record.Nome (@record.MatrOpr)</td>
</tr>
}
</tbody>
+16 -7
View File
@@ -1,4 +1,4 @@
@page "/diario"
@page "/Diario"
@using MP.Stats.Components
@@ -24,7 +24,7 @@
<tr>
<th>Macchina</th>
<th>Data</th>
<th>ODL/Commessa</th>
<th>Commessa/ODL</th>
<th>Articolo</th>
<th class="text-right">Stato</th>
<th class="text-right">Durata</th>
@@ -40,13 +40,22 @@
<div class="small">@record.IdxMacchina</div>
</td>
<td>
<div>@record.InizioStato.ToString("yyyy.MM.dd")</div>
<div class="small">@record.InizioStato.ToString("ddd HH:mm.ss")</div>
<div>@record.InizioPeriodo.ToString("yyyy.MM.dd")</div>
<div class="small">@record.InizioPeriodo.ToString("ddd HH:mm.ss")</div>
</td>
<td>
<div>@record.KeyRichiesta</div>
<div class="small">@record.IdxOdl</div>
</td>
<td>
@record.CodArticolo
<div class="small">@record.DescArticolo</div>
</td>
<td>@record.IdxOdl | @record.KeyRichiesta</td>
<td>@record.CodArticolo</td>
<td class="text-right">@record.Descrizione</td>
<td class="text-right">@record.DurataMin</td>
<td class="text-right">
@MP.Data.Utils.ConvMsecToTime((long)record.DurataPeriodo)
<div class="small">@(((double)record.DurataPeriodo/60000).ToString("N2")) <sub>min</sub></div>
</td>
<td class="text-right">@record.TotPzProd</td>
</tr>
}
+28 -15
View File
@@ -34,9 +34,31 @@ namespace MP.Stats.Pages
}
}
private int currPage { get; set; } = 1;
private int currPage
{
get
{
return currFilter.PageNum;
}
set
{
currFilter.PageNum = value;
}
}
private bool isLoading { get; set; } = false;
private int numRecord { get; set; } = 10;
private int numRecord
{
get
{
return currFilter.PageSize;
}
set
{
currFilter.PageSize = value;
}
}
#endregion Private Properties
@@ -54,18 +76,7 @@ namespace MP.Stats.Pages
[Inject]
protected MpStatsService StatService { get; set; }
protected int totalCount
{
get
{
int answ = 0;
if (SearchRecords != null)
{
answ = SearchRecords.Count;
}
return answ;
}
}
protected int totalCount { get; set; } = 0;
#endregion Protected Properties
@@ -74,8 +85,10 @@ namespace MP.Stats.Pages
private async Task reloadData()
{
isLoading = true;
totalCount = await StatService.StatDdbGetCount(currFilter, MessageService.SearchVal);
SearchRecords = await StatService.StatDdbGetAll(currFilter, MessageService.SearchVal);
ListRecords = SearchRecords.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList();
// faccio paginazione SOLO NELLA DECINA attuale... (quindi non tutte le pagine ma solo subset)
ListRecords = SearchRecords.Skip(numRecord * (currPage % 10 - 1)).Take(numRecord).ToList();
isLoading = false;
}
+5
View File
@@ -0,0 +1,5 @@
@page "/Download"
@model MP.Stats.Pages.DownloadModel
@{
}
+52
View File
@@ -0,0 +1,52 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace MP.Stats.Pages
{
/// <summary>
/// Gestione donwnload file csv
///
/// da valutare eventualmente xlsx con https://github.com/closedxml/closedxml
/// </summary>
public class DownloadModel : PageModel
{
#region Private Fields
private readonly IWebHostEnvironment _env;
#endregion Private Fields
#region Public Constructors
public DownloadModel(IWebHostEnvironment env)
{
_env = env;
}
#endregion Public Constructors
#region Public Methods
public IActionResult OnGet()
{
string fileName = "OUT.csv";
if (Request.Query.ContainsKey("fileName"))
{
fileName = Request.Query["fileName"];
}
var filePath = Path.Combine(_env.WebRootPath, "..\\temp\\", fileName);
byte[] fileBytes = System.IO.File.ReadAllBytes(filePath);
return File(fileBytes, "application/force-download", fileName);
}
#endregion Public Methods
}
}
+11 -7
View File
@@ -1,4 +1,4 @@
@page "/oee"
@page "/Oee"
@using MP.Stats.Components
@@ -30,7 +30,6 @@
<table class="table table-sm table-striped">
<thead>
<tr>
@*<th><button class="btn btn-sm btn-primary" @onclick="() => ResetData()"><span class="oi oi-loop-circular"></span></button></th>*@
<th>Data</th>
<th>Turno</th>
<th>Macchina</th>
@@ -44,8 +43,6 @@
@foreach (var record in ListRecords)
{
<tr class="@checkSelect(record.DataRif, record.Turno, @record.IdxMacchina)">
@*<td><button class="btn btn-sm btn-primary" @onclick="() => Select(record)"><span class="oi oi-magnifying-glass"></span></button></td>*@
<td>
<div>@record.DataRif.ToString("yyyy.MM.dd")</div>
<div class="small">@record.DataRif.ToString("dddd")</div>
@@ -55,8 +52,15 @@
<div>@record.CodMacchina</div>
<div class="small">@record.IdxMacchina</div>
</td>
<td>@record.CodArticolo</td>
<td class="text-right">@record.TotPeriodo.ToString("N2")</td>
<td>
@record.CodArticolo
<div class="small">@record.DescArticolo</div>
</td>
@*<td class="text-right">@record.TotPeriodo.ToString("N2")</td>*@
<td class="text-right">
@MP.Data.Utils.ConvMinToTime((double)record.TotPeriodo)
<div class="small">@record.TotPeriodo.ToString("N2") <sub>min</sub></div>
</td>
<td class="text-right">@record.TotPz</td>
<td class="text-right">@record.OEE.ToString("P2")</td>
</tr>
@@ -68,6 +72,6 @@
}
</div>
<div class="card-footer py-1">
<DataPager PageSize="numRecord" currPage="currPage" numRecordChanged="ForceReload" numPageChanged="ForceReloadPage" totalCount="totalCount" showLoading="isLoading" />
<DataPager PageSize="numRecord" currPage="currPage" numRecordChanged="ForceReload" numPageChanged="ForceReloadPage" exportRequested="ExportCsv" fileName="@fileName" totalCount="totalCount" showLoading="isLoading" />
</div>
</div>
+37 -8
View File
@@ -6,6 +6,11 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.IO;
using System.Threading;
using System.Text;
using System.ComponentModel;
namespace MP.Stats.Pages
{
public partial class Oee : ComponentBase, IDisposable
@@ -14,6 +19,7 @@ namespace MP.Stats.Pages
private MP.Data.DatabaseModels.TurniOee currRecord = null;
private string fileName = "OEE.csv";
private List<MP.Data.DatabaseModels.TurniOee> ListRecords;
private List<MP.Data.DatabaseModels.TurniOee> SearchRecords;
@@ -46,12 +52,17 @@ namespace MP.Stats.Pages
if (_currPage != value)
{
_currPage = value;
var pUpd = Task.Run(async () => await reloadData());
var pUpd = Task.Run(async () => await ReloadData());
pUpd.Wait();
}
}
}
private string fullPath
{
get => $"{Directory.GetCurrentDirectory()}\\temp\\{fileName}";
}
private bool isLoading { get; set; } = false;
private int numRecord
@@ -62,7 +73,7 @@ namespace MP.Stats.Pages
if (_numRecord != value)
{
_numRecord = value;
var pUpd = Task.Run(async () => await reloadData());
var pUpd = Task.Run(async () => await ReloadData());
pUpd.Wait();
}
}
@@ -103,7 +114,21 @@ namespace MP.Stats.Pages
#region Private Methods
private async Task reloadData()
private async void clearFile()
{
await Task.Run(() => File.Delete(fullPath));
}
private async Task ExportCsv()
{
isLoading = true;
// calcolo nome file
// salvo davvero!
await MP.Data.Utils.SaveToCsv(SearchRecords, fullPath);
isLoading = false;
}
private async Task ReloadData()
{
isLoading = true;
SearchRecords = await StatService.StatTurniOeeGetAllCached(currFilter, MessageService.SearchVal);
@@ -117,11 +142,12 @@ namespace MP.Stats.Pages
protected async Task DoFilter(SelectData newFilter)
{
clearFile();
currRecord = null;
SearchRecords = null;
ListRecords = null;
currFilter = newFilter;
await reloadData();
await ReloadData();
}
protected void ForceReload(int newNum)
@@ -136,27 +162,30 @@ namespace MP.Stats.Pages
protected override async Task OnInitializedAsync()
{
clearFile();
numRecord = 10;
MessageService.ShowSearch = false;
MessageService.PageName = "TRS/OEE %";
MessageService.PageIcon = "oi oi-monitor";
MessageService.EA_SearchUpdated += OnSeachUpdated;
await reloadData();
await ReloadData();
}
protected void ResetData()
{
clearFile();
StatService.rollBackEdit(currRecord);
currRecord = null;
}
protected async Task ResetFilter(SelectData newFilter)
{
clearFile();
currRecord = null;
SearchRecords = null;
ListRecords = null;
currFilter = SelectData.Init(5, 7);
await reloadData();
await ReloadData();
}
protected void Select(MP.Data.DatabaseModels.TurniOee selRecord)
@@ -170,14 +199,14 @@ namespace MP.Stats.Pages
ShowCharts = !ShowCharts;
if (ShowCharts)
{
await reloadData();
await ReloadData();
}
}
protected async Task UpdateData()
{
currRecord = null;
await reloadData();
await ReloadData();
}
#endregion Protected Methods
+11 -7
View File
@@ -1,4 +1,4 @@
@page "/reportodl"
@page "/ReportOdl"
@using MP.Stats.Components
@@ -23,7 +23,7 @@
<thead>
<tr>
<th>Macchina</th>
<th>ODL/Commessa</th>
<th>Commessa/ODL</th>
<th>Articolo</th>
<th>Inizio</th>
<th>Fine</th>
@@ -37,17 +37,21 @@
@foreach (var record in ListRecords)
{
<tr class="@checkSelect(@record.IdxOdl)">
<td>@record.IdxMacchina</td>
<td>
@record.IdxMacchina
<div>@record.KeyRichiesta</div>
<div class="small">@record.IdxOdl</div>
</td>
<td>
@record.CodArticolo
<div class="small">@record.DescArticolo</div>
</td>
<td>@record.IdxOdl | @record.KeyRichiesta</td>
<td>@record.CodArticolo</td>
<td>@record.DataInizio</td>
<td>@record.DataFine</td>
<td class="text-right">@record.NumPezzi</td>
<td class="text-right">@record.NumPezziEv</td>
<td class="text-right">@record.NumPezziRil</td>
<td class="text-right">@record.NumPezziSca</td>
<td class="text-right">@record.NumPezziRil</td>
</tr>
}
</tbody>
@@ -57,6 +61,6 @@
}
</div>
<div class="card-footer py-1">
<DataPager PageSize="numRecord" currPage="currPage" numRecordChanged="ForceReload" numPageChanged="ForceReloadPage" totalCount="totalCount" />
<DataPager PageSize="numRecord" currPage="currPage" numRecordChanged="ForceReload" numPageChanged="ForceReloadPage" exportRequested="ExportCsv" fileName="@fileName" totalCount="totalCount" showLoading="isLoading" />
</div>
</div>
+38 -7
View File
@@ -3,6 +3,7 @@ using Microsoft.JSInterop;
using MP.Stats.Data;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
@@ -19,6 +20,12 @@ namespace MP.Stats.Pages
#endregion Private Fields
#region Protected Fields
protected string fileName = "ODL.csv";
#endregion Protected Fields
#region Private Properties
private SelectData currFilter
@@ -34,6 +41,13 @@ namespace MP.Stats.Pages
}
private int currPage { get; set; } = 1;
private string fullPath
{
get => $"{Directory.GetCurrentDirectory()}\\temp\\{fileName}";
}
private bool isLoading { get; set; } = false;
private int numRecord { get; set; } = 10;
#endregion Private Properties
@@ -69,7 +83,20 @@ namespace MP.Stats.Pages
#region Private Methods
private async Task reloadData()
private async void clearFile()
{
await Task.Run(() => File.Delete(fullPath));
}
private async Task ExportCsv()
{
isLoading = true;
// salvo davvero!
await MP.Data.Utils.SaveToCsv(SearchRecords, fullPath);
isLoading = false;
}
private async Task ReloadData()
{
SearchRecords = await StatService.StatOdlGetAll(currFilter, MessageService.SearchVal);
ListRecords = SearchRecords.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList();
@@ -81,53 +108,57 @@ namespace MP.Stats.Pages
protected async Task DoFilter(SelectData newFilter)
{
clearFile();
SearchRecords = null;
ListRecords = null;
currFilter = newFilter;
await reloadData();
await ReloadData();
}
protected async Task ForceReload(int newNum)
{
numRecord = newNum;
await reloadData();
await ReloadData();
}
protected async Task ForceReloadPage(int newNum)
{
currPage = newNum;
await reloadData();
await ReloadData();
}
protected override async Task OnInitializedAsync()
{
clearFile();
numRecord = 10;
MessageService.ShowSearch = false;
MessageService.PageName = "Report ODL/Comm.";
MessageService.PageIcon = "oi oi-book";
MessageService.EA_SearchUpdated += OnSeachUpdated;
await reloadData();
await ReloadData();
}
protected void ResetData()
{
clearFile();
StatService.rollBackEdit(currRecord);
currRecord = null;
}
protected async Task ResetFilter(SelectData newFilter)
{
clearFile();
currRecord = null;
SearchRecords = null;
ListRecords = null;
currFilter = SelectData.Init(5, 7);
await reloadData();
await ReloadData();
}
protected async Task UpdateData()
{
currRecord = null;
await reloadData();
await ReloadData();
}
#endregion Protected Methods
+9 -3
View File
@@ -29,7 +29,7 @@
<tr>
<th>Macchina</th>
<th>Data</th>
<th>ODL/Commessa</th>
<th>Commessa/ODL</th>
<th>Articolo</th>
<th class="text-right">Descrizione</th>
<th class="text-right">Qta</th>
@@ -48,8 +48,14 @@
<div>@record.DataOraRif.ToString("yyyy.MM.dd")</div>
<div class="small">@record.DataOraRif.ToString("ddd HH:mm.ss")</div>
</td>
<td>@record.IdxOdl | @record.KeyRichiesta</td>
<td>@record.CodArticolo</td>
<td>
<div>@record.KeyRichiesta</div>
<div class="small">@record.IdxOdl</div>
</td>
<td>
@record.CodArticolo
<div class="small">@record.DescArticolo</div>
</td>
<td class="text-right">
<div class="row">
<div class="col">[@record.Causale]</div>
+11 -5
View File
@@ -1,4 +1,4 @@
@page "/userlog"
@page "/UserLog"
@*@page "/userlog/{IdxMacchina}"*@
@using MP.Stats.Components
@@ -29,7 +29,7 @@
<tr>
<th>Macchina</th>
<th>Data</th>
<th>ODL/Commessa</th>
<th>Commessa/ODL</th>
<th>Articolo</th>
<th class="text-right">Descrizione</th>
<th class="text-right">Qta</th>
@@ -48,11 +48,17 @@
<div>@record.DataOraRif.ToString("yyyy.MM.dd")</div>
<div class="small">@record.DataOraRif.ToString("ddd HH:mm.ss")</div>
</td>
<td>@record.IdxOdl | @record.KeyRichiesta</td>
<td>@record.CodArticolo</td>
<td>
<div>@record.KeyRichiesta</div>
<div class="small">@record.IdxOdl</div>
</td>
<td>
@record.CodArticolo
<div class="small">@record.DescArticolo</div>
</td>
<td class="text-right">
<div>@record.Valore</div>
<div class="small row">
<div class="small row text-nowrap">
<div class="col">
<span class="@decodeAction(@record.Azione).Class" aria-hidden="true"></span> [@record.IdxLog]
</div>
@@ -6,6 +6,6 @@ by editing this MSBuild file. In order to learn more about this please visit htt
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<TimeStampOfAssociatedLegacyPublishXmlFile />
<History>True|2021-05-26T17:51:13.5051479Z;True|2021-05-26T19:51:04.9283608+02:00;True|2021-05-25T16:38:26.4142377+02:00;</History>
<History>True|2021-05-27T09:13:55.8234781Z;True|2021-05-26T19:51:13.5051479+02:00;True|2021-05-26T19:51:04.9283608+02:00;True|2021-05-25T16:38:26.4142377+02:00;</History>
</PropertyGroup>
</Project>
+5 -5
View File
@@ -13,7 +13,7 @@
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="oee">
<NavLink class="nav-link" href="Oee">
<span class="oi oi-monitor" aria-hidden="true"></span> TRS/OEE %
</NavLink>
</li>
@@ -23,22 +23,22 @@
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="diario">
<NavLink class="nav-link" href="Diario">
<span class="oi oi-clipboard" aria-hidden="true" title="Dettaglio dati di Produzione"></span> Diario Produzione
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="userlog">
<NavLink class="nav-link" href="UserLog">
<span class="oi oi-document" aria-hidden="true" title="Statistiche Controlli"></span> User ActionLog
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="controlli">
<NavLink class="nav-link" href="Controlli">
<span class="oi oi-beaker" aria-hidden="true" title="Registro Controlli"></span> Registro Controlli
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="scarti">
<NavLink class="nav-link" href="Scarti">
<span class="oi oi-warning" aria-hidden="true" title="Registro Scarti"></span> Registro Scarti
</NavLink>
</li>
-1
View File
@@ -105,7 +105,6 @@ namespace MP.Stats
services.AddSingleton<IConfiguration>(Configuration);
services.AddTransient<Services.BlazorTimer>();
//services.AddScoped<BBM_SelectData>();
services.AddSingleton<MpStatsService>();
services.AddScoped<MessageService>();
}
+2 -1
View File
@@ -10,5 +10,6 @@
"ConnectionStrings": {
"DefaultConnection": "Server=SQL2016DEV;Database=MoonPro_STATS;Trusted_Connection=True;MultipleActiveResultSets=true",
"Mp.Stats": "Server=SQL2016DEV;Database=MoonPro_STATS;User ID=sa;Password=keyhammer16;integrated security=False;MultipleActiveResultSets=True;App=MP.STATS;"
}
},
"FormatDur": "HH:mm.ss.ff"
}
+24 -1
View File
@@ -1,11 +1,34 @@
param([string]$ProjectDir, [string]$ProjectPath);
$FileVers="..\Resources\VersNum.txt"
$FileManIn="..\Resources\manifest-original.xml"
$FileManOut="..\Resources\manifest.xml"
$FileCLogIn="..\Resources\ChangeLog-original.html"
$FileCLogOut="..\Resources\ChangeLog.html"
$MajMin="1.0."
$currentDate = get-date -format yyMM;
$currentTime = get-date -format ddHH;
$find = "<Version>(.|\n)*?</Version>";
$currRelNum=$MajMin + $currentDate +"." + $currentTime
$replace = "<Version>" + $MajMin + $currentDate +"." + $currentTime + "</Version>";
$csproj = Get-Content $ProjectPath
$csprojUpdated = $csproj -replace $find, $replace
Set-Content -Path $ProjectPath -Value $csprojUpdated
Set-Content -Path $ProjectPath -Value $csprojUpdated
Set-Content -Path $FileVers -Value $currRelNum
# replace x manifest
$manData = Get-Content $FileManIn
$manData = $manData -replace "1.0.0.0", $currRelNum
$manData = $manData -replace "{{DIRNAME}}", "MP-STATS"
$manData = $manData -replace "{{BRANCHNAME}}", "stable/0"
$manData = $manData -replace "{{PACKNAME}}", "MP.Stats"
Set-Content -Path $FileManOut -Value $manData
# replace x ChangeLog
$clogData = Get-Content $FileCLogIn
$clogData = $clogData -replace "{{CURRENT-REL}}", $currRelNum
# $clogData = $clogData -replace "{{DIRNAME}}", "MP-STATS"
# $clogData = $clogData -replace "{{BRANCHNAME}}", "stable"
# $clogData = $clogData -replace "{{PACKNAME}}", "MP.Stats"
Set-Content -Path $FileCLogOut -Value $clogData
+1
View File
@@ -0,0 +1 @@

+5 -1
View File
@@ -6,7 +6,11 @@ h3,
h4,
h5,
h6,
b {
b,
display-1,
display-2,
display-3,
display-4 {
font-family: 'Roboto', sans-serif;
}
html,
+1 -1
View File
@@ -1,7 +1,7 @@
@import url('open-iconic/font/css/open-iconic-bootstrap.min.css');
@import url('fonts.min.css');
h1, h2, h3, h4, h5, h6, b {
h1, h2, h3, h4, h5, h6, b, display-1, display-2, display-3, display-4 {
font-family: 'Roboto', sans-serif;
}
+1 -1
View File
@@ -1 +1 @@
@import url('open-iconic/font/css/open-iconic-bootstrap.min.css');@import url('fonts.min.css');h1,h2,h3,h4,h5,h6,b{font-family:'Roboto',sans-serif;}html,body{font-family:'Lato',sans-serif;}a,.btn-link{color:#0366d6;}.btn-primary{color:#fff;background-color:#1b6ec2;border-color:#1861ac;}.content{padding-top:1.1rem;}.valid.modified:not([type=checkbox]){outline:1px solid #26b050;}.invalid{outline:1px solid #f00;}.validation-message{color:#f00;}#blazor-error-ui{background:#ffffe0;bottom:0;box-shadow:0 -1px 2px rgba(0,0,0,.2);display:none;left:0;padding:.6rem 1.25rem .7rem 1.25rem;position:fixed;width:100%;z-index:1000;}#blazor-error-ui .dismiss{cursor:pointer;position:absolute;right:.75rem;top:.5rem;}.shortcuts{text-align:center;}.shortcuts .shortcut-icon{font-size:2rem;}.shortcuts .shortcut{min-width:9rem;min-height:5rem;display:inline-block;padding:.66666667rem 0;margin:0 2px 1em;vertical-align:top;text-decoration:none;background:#f3f3f3;background-image:-webkit-gradient(linear,left 0%,left 100%,from(#fff),to(#eee));background-image:-webkit-linear-gradient(top,#fff,0%,#eee,100%);background-image:-moz-linear-gradient(top,#fff 0%,#eee 100%);background-image:linear-gradient(to bottom,#fff 0%,#eee 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffeeeeee',GradientType=0);border:1px solid #ddd;box-sizing:border-box;border-radius:.5rem;}.shortcuts .shortcut-sm{min-width:4.5rem;min-height:3rem;display:inline-block;padding:.25rem 0;margin:0 2px 1em;vertical-align:top;text-decoration:none;background:#f3f3f3;background-image:-webkit-gradient(linear,left 0%,left 100%,from(#fff),to(#eee));background-image:-webkit-linear-gradient(top,#fff,0%,#eee,100%);background-image:-moz-linear-gradient(top,#fff 0%,#eee 100%);background-image:linear-gradient(to bottom,#fff 0%,#eee 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffeeeeee',GradientType=0);border:1px solid #ddd;box-sizing:border-box;border-radius:.5rem;}.shortcuts .shortcut .shortcut-icon{width:100%;margin-top:0;margin-bottom:0;font-size:2rem;color:#333;}.shortcuts .shortcut-sm .shortcut-icon{width:100%;margin-top:0;margin-bottom:0;font-size:2rem;color:#333;}.shortcuts .shortcut:hover{background:#e8e8e8;background-image:-webkit-gradient(linear,left 0%,left 100%,from(#fafafa),to(#e1e1e1));background-image:-webkit-linear-gradient(top,#fafafa,0%,#e1e1e1,100%);background-image:-moz-linear-gradient(top,#fafafa 0%,#e1e1e1 100%);background-image:linear-gradient(to bottom,#fafafa 0%,#e1e1e1 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffafafa',endColorstr='#ffe1e1e1',GradientType=0);}.shortcuts .shortcut-sm:hover{background:#e8e8e8;background-image:-webkit-gradient(linear,left 0%,left 100%,from(#fafafa),to(#e1e1e1));background-image:-webkit-linear-gradient(top,#fafafa,0%,#e1e1e1,100%);background-image:-moz-linear-gradient(top,#fafafa 0%,#e1e1e1 100%);background-image:linear-gradient(to bottom,#fafafa 0%,#e1e1e1 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffafafa',endColorstr='#ffe1e1e1',GradientType=0);}.shortcuts .shortcut:active{box-shadow:inset 0 3px 5px rgba(0,0,0,.125);}.shortcuts .shortcut-sm:active{box-shadow:inset 0 3px 5px rgba(0,0,0,.125);}.shortcuts .shortcut:hover .shortcut-icon{color:#c93;}.shortcuts .shortcut-sm:hover .shortcut-icon{color:#666;}.shortcuts .shortcut-label{display:block;margin-top:.75em;font-weight:400;color:#666;}@media(max-width:992px){.shortcuts .shortcut{min-width:8rem;min-height:4rem;}}
@import url('open-iconic/font/css/open-iconic-bootstrap.min.css');@import url('fonts.min.css');h1,h2,h3,h4,h5,h6,b,display-1,display-2,display-3,display-4{font-family:'Roboto',sans-serif;}html,body{font-family:'Lato',sans-serif;}a,.btn-link{color:#0366d6;}.btn-primary{color:#fff;background-color:#1b6ec2;border-color:#1861ac;}.content{padding-top:1.1rem;}.valid.modified:not([type=checkbox]){outline:1px solid #26b050;}.invalid{outline:1px solid #f00;}.validation-message{color:#f00;}#blazor-error-ui{background:#ffffe0;bottom:0;box-shadow:0 -1px 2px rgba(0,0,0,.2);display:none;left:0;padding:.6rem 1.25rem .7rem 1.25rem;position:fixed;width:100%;z-index:1000;}#blazor-error-ui .dismiss{cursor:pointer;position:absolute;right:.75rem;top:.5rem;}.shortcuts{text-align:center;}.shortcuts .shortcut-icon{font-size:2rem;}.shortcuts .shortcut{min-width:9rem;min-height:5rem;display:inline-block;padding:.66666667rem 0;margin:0 2px 1em;vertical-align:top;text-decoration:none;background:#f3f3f3;background-image:-webkit-gradient(linear,left 0%,left 100%,from(#fff),to(#eee));background-image:-webkit-linear-gradient(top,#fff,0%,#eee,100%);background-image:-moz-linear-gradient(top,#fff 0%,#eee 100%);background-image:linear-gradient(to bottom,#fff 0%,#eee 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffeeeeee',GradientType=0);border:1px solid #ddd;box-sizing:border-box;border-radius:.5rem;}.shortcuts .shortcut-sm{min-width:4.5rem;min-height:3rem;display:inline-block;padding:.25rem 0;margin:0 2px 1em;vertical-align:top;text-decoration:none;background:#f3f3f3;background-image:-webkit-gradient(linear,left 0%,left 100%,from(#fff),to(#eee));background-image:-webkit-linear-gradient(top,#fff,0%,#eee,100%);background-image:-moz-linear-gradient(top,#fff 0%,#eee 100%);background-image:linear-gradient(to bottom,#fff 0%,#eee 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffeeeeee',GradientType=0);border:1px solid #ddd;box-sizing:border-box;border-radius:.5rem;}.shortcuts .shortcut .shortcut-icon{width:100%;margin-top:0;margin-bottom:0;font-size:2rem;color:#333;}.shortcuts .shortcut-sm .shortcut-icon{width:100%;margin-top:0;margin-bottom:0;font-size:2rem;color:#333;}.shortcuts .shortcut:hover{background:#e8e8e8;background-image:-webkit-gradient(linear,left 0%,left 100%,from(#fafafa),to(#e1e1e1));background-image:-webkit-linear-gradient(top,#fafafa,0%,#e1e1e1,100%);background-image:-moz-linear-gradient(top,#fafafa 0%,#e1e1e1 100%);background-image:linear-gradient(to bottom,#fafafa 0%,#e1e1e1 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffafafa',endColorstr='#ffe1e1e1',GradientType=0);}.shortcuts .shortcut-sm:hover{background:#e8e8e8;background-image:-webkit-gradient(linear,left 0%,left 100%,from(#fafafa),to(#e1e1e1));background-image:-webkit-linear-gradient(top,#fafafa,0%,#e1e1e1,100%);background-image:-moz-linear-gradient(top,#fafafa 0%,#e1e1e1 100%);background-image:linear-gradient(to bottom,#fafafa 0%,#e1e1e1 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffafafa',endColorstr='#ffe1e1e1',GradientType=0);}.shortcuts .shortcut:active{box-shadow:inset 0 3px 5px rgba(0,0,0,.125);}.shortcuts .shortcut-sm:active{box-shadow:inset 0 3px 5px rgba(0,0,0,.125);}.shortcuts .shortcut:hover .shortcut-icon{color:#c93;}.shortcuts .shortcut-sm:hover .shortcut-icon{color:#666;}.shortcuts .shortcut-label{display:block;margin-top:.75em;font-weight:400;color:#666;}@media(max-width:992px){.shortcuts .shortcut{min-width:8rem;min-height:4rem;}}
+27
View File
@@ -0,0 +1,27 @@
<body>
<i>Modulo statistiche MAPO</i>
<h4>Versione: {{CURRENT-REL}}</h4>
<br />
Note di rilascio:
<ul>
<li>
<b>Ultime modifiche:</b>
<ul>{{LAST-CHANGES}}</ul>
</li>
<li>
<b>v.1.* &rarr;</b>
<ul>
<li>Prima release dotnet5</li>
<li>Integrazione EFCore</li>
</ul>
</li>
</ul>
<div>
<div style="float: left;">
<img src="logoSteamware.png" />
</div>
<div style="float: right;">
<a href="https://www.steamware.net/IOT" target="_blank">&copy; Steamware 2006-2021</a>
</div>
</div>
</body>
+27
View File
@@ -0,0 +1,27 @@
<body>
<i>Modulo statistiche MAPO</i>
<h4>Versione: 1.0.2107.0219</h4>
<br />
Note di rilascio:
<ul>
<li>
<b>Ultime modifiche:</b>
<ul>{{LAST-CHANGES}}</ul>
</li>
<li>
<b>v.1.* &rarr;</b>
<ul>
<li>Prima release dotnet5</li>
<li>Integrazione EFCore</li>
</ul>
</li>
</ul>
<div>
<div style="float: left;">
<img src="logoSteamware.png" />
</div>
<div style="float: right;">
<a href="https://www.steamware.net/IOT" target="_blank">&copy; Steamware 2006-2021</a>
</div>
</div>
</body>
+1
View File
@@ -0,0 +1 @@
1.0.2107.0219
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

+7
View File
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<item>
<version>1.0.0.0</version>
<url>http://nexus.steamware.net/repository/SWS/{{DIRNAME}}/{{BRANCHNAME}}/{{PACKNAME}}.zip</url>
<changelog>http://nexus.steamware.net/repository/SWS/{{DIRNAME}}/{{BRANCHNAME}}/ChangeLog.html</changelog>
<mandatory>false</mandatory>
</item>
+7
View File
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<item>
<version>1.0.2107.0219</version>
<url>http://nexus.steamware.net/repository/SWS/MP-STATS/stable/0/MP.Stats.zip</url>
<changelog>http://nexus.steamware.net/repository/SWS/MP-STATS/stable/0/ChangeLog.html</changelog>
<mandatory>false</mandatory>
</item>