Compare commits

..

100 Commits

Author SHA1 Message Date
Samuele Locatelli 587f0accbe Merge branch 'release/FixStatsSlowInit' 2021-09-16 17:37:08 +02:00
Samuele Locatelli 8d57772e35 Merge branch 'feature/CheckStats' into develop 2021-09-16 17:36:39 +02:00
Samuele Locatelli c2464d2b47 COmpletato fix inizializzazione selettore filtro x errore se tarda caricamento 2021-09-16 17:36:30 +02:00
Samuele Locatelli 01adbcb666 Update NuGet EFCore 2021-09-16 17:27:39 +02:00
Samuele Locatelli 1ec0c7d5a9 Update NuGet Elmah 2021-09-16 17:25:39 +02:00
Samuele Locatelli a93d84eea1 update nuget NLog 2021-09-16 17:25:06 +02:00
Samuele Locatelli 88795e5991 Merge tag 'FixDeployNexus' into develop
Fix nexus deploy x zip e allegati
2021-09-16 12:53:09 +02:00
Samuele Locatelli a1486ad04b Merge branch 'release/FixDeployNexus' 2021-09-16 12:52:56 +02:00
Samuele Locatelli 14b808429d Fix NEXUS_PATH x deploy 2021-09-16 12:46:27 +02:00
Samuele Locatelli 4346cb5cca Merge tag 'Debounce' into develop
Fix debounce
2021-09-16 12:38:41 +02:00
Samuele Locatelli ca6eea7f80 Merge branch 'release/Debounce' 2021-09-16 12:38:36 +02:00
Samuele Locatelli 02bcec21ad Merge tag 'Vers_1.1' into develop
Inserimento progetto MP-PROG
2021-09-16 12:36:49 +02:00
Samuele Locatelli ae7213c5a7 Merge branch 'release/Vers_1.1' 2021-09-16 12:36:27 +02:00
Samuele Locatelli 2af0674f1f COmpletato debounce con componente ad hoc 2021-09-16 12:36:11 +02:00
Samuele Locatelli 27100c7d65 Completata search libera (senza debounce da sistemare) 2021-09-16 10:55:09 +02:00
Samuele Locatelli c27b81f506 Fix vari x logging + refresh 2021-09-16 09:08:05 +02:00
Samuele Locatelli 09b3c98199 update recupero vers number 2021-09-15 19:46:02 +02:00
Samuele Locatelli 92fd05d32d ancora correzione yaml 2021-09-15 19:41:00 +02:00
Samuele Locatelli e923a44d99 correzioni yaml 2021-09-15 19:36:07 +02:00
Samuele Locatelli 7cd141f10e http --> https x nexus 2021-09-15 19:30:01 +02:00
Samuele Locatelli 26cbdc88af fix nexus upload (maybe) 2021-09-15 19:28:43 +02:00
Samuele Locatelli 2898dcd433 Fix generazione versioni 2021-09-15 19:10:26 +02:00
Samuele Locatelli 13fc227875 Fix gesitone resources anche x MP-STATS 2021-09-15 19:09:24 +02:00
Samuele Locatelli f5a0b6a3a9 Fix MP.Prog x versNumb 2021-09-15 19:09:15 +02:00
Samuele Locatelli bf1df41d04 Aggiunto script x PostBuild 2021-09-15 18:49:53 +02:00
Samuele Locatelli ad83a7a14a Aggiunta resources in dir locale PROG 2021-09-15 18:49:46 +02:00
Samuele Locatelli 4c1c0bfac7 Fix configurazione DB x startup 2021-09-15 18:36:37 +02:00
Samuele Locatelli b0bfff9d9f Fix conf staging e produzione x DB 2021-09-15 18:30:43 +02:00
Samuele Locatelli 28e548003b Fix deploy x PROG appsettings.staging.json 2021-09-15 18:21:17 +02:00
Samuele Locatelli 0af4a4e488 Merge branch 'feature/DeployProg' into develop 2021-09-15 18:15:24 +02:00
Samuele Locatelli fea8d06a12 test yaml gitlab 2021-09-15 18:09:21 +02:00
Samuele Locatelli 5600427d71 Update file pubblicazione 2021-09-15 18:09:09 +02:00
Samuele Locatelli cf2f9de185 aggiunta publish profile prog 2021-09-15 18:08:53 +02:00
Samuele Locatelli e3f9f534da Introduzione Tag Search 2021-09-15 17:12:05 +02:00
Samuele Locatelli 3932a5330b Merge branch 'feature/SearchReview' into develop 2021-09-15 13:11:40 +02:00
Samuele Locatelli 2a42571375 Aggiunta ricerca "non taggati" 2021-09-15 13:11:19 +02:00
Samuele Locatelli 3aa8341c94 Ricerca x Tag (singolo) 2021-09-15 13:03:23 +02:00
Samuele Locatelli 18596a9168 Ricerca x nome file 2021-09-15 12:51:46 +02:00
Samuele Locatelli 5c49bb6b6a Merge branch 'feature/TagDecodeUpdate' into develop 2021-09-14 19:27:24 +02:00
Samuele Locatelli 3f4f9965e8 Ancora fix procedura decodifica tags 2021-09-14 19:27:16 +02:00
Samuele Locatelli 6fe3925ad8 Avanzamento gestione decodifica tornoss e MTH 2021-09-14 16:43:20 +02:00
Samuele Locatelli 1652697aff Conf x tornos TISIS + MTH 2021-09-14 16:43:08 +02:00
Samuele Locatelli cc9901e5f9 Merge branch 'feature/FilterUpdate' into develop 2021-09-14 13:15:23 +02:00
Samuele Locatelli c4acee1632 UPdate info in refresh ricalcolo 2021-09-14 13:15:14 +02:00
Samuele Locatelli 07a6978e01 Continuo pagina setup x ricalcolo completo archivio 2021-09-14 07:53:08 +02:00
Samuele Locatelli a5e0100cab Fix ricerca con paginazione da DB 2021-09-13 18:15:59 +02:00
Samuele Locatelli 6940a68c0c udpate paginazione dati solo decina apgine correnti 2021-09-13 18:05:43 +02:00
Samuele Locatelli 48ee4dcdae update datamodel file con indici 2021-09-13 18:05:31 +02:00
Samuele Locatelli 758810be12 Modifica comportamento UI x display update 2021-09-13 15:41:21 +02:00
Samuele Locatelli a8416ca3bc Spostato ricalcolo totale in setup 2021-09-13 15:40:49 +02:00
Samuele Locatelli fe279af47b Merge branch 'feature/TagArtDataModelFix' into develop 2021-09-13 11:43:43 +02:00
Samuele Locatelli 461b00dc90 Fix display update caricamento pagina 2021-09-13 11:43:30 +02:00
Samuele Locatelli 66a2fd0923 refresh con pager 2021-09-13 08:46:58 +02:00
Samuele Locatelli 7fb3e35416 Modifica controllo file (con ricerdca ultime modifiche) 2021-09-13 08:46:52 +02:00
Samuele Locatelli 7ce2d0720c Fix componente DataPager 2021-09-13 08:46:32 +02:00
Samuele Locatelli 3ae71e73a8 OK decode biglia 445 (tranne nomi file sbagliati) + fix 446 tags 2021-09-09 17:03:35 +02:00
Samuele Locatelli 60a8d3b8a6 update x step gestione conf serializzata json 2021-09-08 14:53:02 +02:00
Samuele Locatelli 93423b93b5 Cambio datamodel macchina x gestione ruoli json conf 2021-09-08 14:52:51 +02:00
Samuele Locatelli 08703a9593 Creato classe x parametrizzare gest TAGS 2021-09-08 13:28:48 +02:00
Samuele Locatelli 7633bf5040 Ok x importare maggioranza tags 2021-09-08 12:33:11 +02:00
Samuele Locatelli 8b3fa36524 Ancora update in import Tags 2021-09-08 11:00:34 +02:00
Samuele Locatelli 0f2013c75f Ok ricerca preliminare tags da file 2021-09-08 10:41:23 +02:00
Samuele Locatelli 82736ca983 update x nuova gestione senza articolo 2021-09-08 09:32:11 +02:00
Samuele Locatelli 9dfa8d2de5 Eliminaizone articolo da struttura DB 2021-09-08 09:32:04 +02:00
Samuele Locatelli 4377e1236c review migrazioni 2021-09-08 09:31:53 +02:00
Samuele Locatelli 1b9590e1eb Merge branch 'feature/GestUpdateMod' into develop 2021-09-07 19:17:41 +02:00
Samuele Locatelli 630f381674 COmpletato comportamento editing accetta/rifiuta 2021-09-07 19:17:32 +02:00
Samuele Locatelli a387d9cd77 Componente differ inserito ed aggiornato 2021-09-07 18:03:35 +02:00
Samuele Locatelli 0e2030ba9e Fix verifica modifica file 2021-09-07 14:22:30 +02:00
Samuele Locatelli 30172c3bfc Fix comportamento selezione attributo status file 2021-09-07 14:22:24 +02:00
Samuele Locatelli 98b9a83491 Update datamodel 2021-09-07 13:28:06 +02:00
Samuele Locatelli e5d6f579f4 refresh archive page 2021-09-07 12:03:09 +02:00
Samuele Locatelli 607e096609 modifica (importante) modallo dati x tags + MD% check 2021-09-07 12:03:01 +02:00
Samuele Locatelli 68b9cd4d78 Abbozzato controllo x filtraggio dati ricerca articoli 2021-09-06 18:34:38 +02:00
Samuele Locatelli c783a2d959 Aggiunta preliminare editor contenuto file 2021-09-06 15:40:58 +02:00
Samuele Locatelli 81430d9b27 refresh 2021-09-06 15:05:01 +02:00
Samuele Locatelli 44f148d41b Ancora update gestione editing file 2021-09-06 15:04:56 +02:00
Samuele Locatelli 13c7bb688c Inizio aggiunta controller editing file 2021-09-06 15:04:39 +02:00
Samuele Locatelli 54526335aa Merge branch 'feature/ArchivioFilePage' into develop 2021-09-03 18:31:08 +02:00
Samuele Locatelli d2300036db COmpletata visualizzazione ArchivioFilePage 2021-09-03 18:31:00 +02:00
Samuele Locatelli 7c80e1aaaf Prima versione caricamento dati NUOVI da filesystem 2021-09-03 18:01:58 +02:00
Samuele Locatelli 50ed15b0ca Update migrazione DB x size file 2021-09-03 18:01:45 +02:00
Samuele Locatelli 4d9563c4b7 Refresh 2021-09-03 16:30:38 +02:00
Samuele Locatelli b53ee95d24 Merge branch 'feature/MP.DataModelCreation' into develop 2021-09-03 16:30:04 +02:00
Samuele Locatelli b1fef48b1c Completata prima integrazione lettura dati dal DB 2021-09-03 16:29:55 +02:00
Samuele Locatelli 17ca3eee8e Fix init DB 2021-09-03 14:58:55 +02:00
Samuele Locatelli e54a77d85d Fix prima navigazione home/archivio programmi 2021-09-03 14:32:24 +02:00
Samuele Locatelli 4f62986402 Integrazione dati x archivio file 2021-09-03 13:24:02 +02:00
Samuele Locatelli 3993f8dc02 Update progetto e main layout 2021-09-03 11:49:34 +02:00
Samuele Locatelli 5e7d966a93 Fix model + migration x DB 2021-09-03 11:49:06 +02:00
Samuele Locatelli 4e64ddb80b refresh progetto 2021-09-03 11:17:15 +02:00
Samuele Locatelli 6e9e89cc85 Update modelli dati 2021-09-03 11:17:06 +02:00
Samuele Locatelli a6617038f7 Merge branch 'feature/MP.ProgManager' into develop 2021-09-02 18:37:20 +02:00
Samuele Locatelli ad2a56c486 Chiudo con implementazione modello dati 2021-09-02 18:37:11 +02:00
Samuele Locatelli 5099bdb1a4 refresh nuget 2021-09-02 18:18:46 +02:00
Samuele Locatelli e7ec7bab2f conf file json vari 2021-09-02 18:18:41 +02:00
Samuele Locatelli b8c7d3236b update librerie client 2021-09-02 18:18:33 +02:00
Samuele Locatelli 98c14b5f06 Update ed aggiunta preliminare componenti 2021-09-02 18:07:46 +02:00
Samuele Locatelli 7f4457783c Aggiunta preliminare progetto MP.Prog 2021-09-02 17:52:56 +02:00
Samuele Locatelli 195bb78554 Merge tag 'FixCICD' into develop
Fix tag win x build dei 2 nuovi runners
2021-09-02 12:52:43 +02:00
317 changed files with 109763 additions and 170 deletions
+3 -86
View File
@@ -7,8 +7,8 @@
#--------------------------------
# area MP.Stats
#--------------------------------
/Mp.Stats/temp/*.csv
/Mp.FileData/temp/*.csv
*.bak
#--------------------------------
# Area VersGen
@@ -16,90 +16,6 @@
/VersGen/bin/*
/VersGen/obj/*
#--------------------------------
# area MapoDb
#--------------------------------
/MapoDb/bin/*
/MapoDb/obj/*
#--------------------------------
# area MP
#--------------------------------
/MP/bin/*
/MP/obj/*
MP/logs/*.txt
MP/logs/*.zip
MP-LAND/logs/
#--------------------------------
# Area MP-MON (MoonPro-MONitor)
#--------------------------------
/MP-MON/logs/*.zip
/MP-MON/logs/*.txt
/MP-MON/bin/*
/MP-MON/obj/*
/MP-MON/WebCharts/*.png
#--------------------------------
# Area MP-IO (MoonPro-IO)
#--------------------------------
/MP-IO/logs/*.zip
/MP-IO/logs/*.txt
/MP-IO/bin/*
/MP-IO/obj/*
/MP-IO/fileUpload/
!/MP-IO/fileUpload/.PlaceHolder.file
#--------------------------------
# Area MP-Admin
#--------------------------------
/MP-Admin/logs/*.zip
/MP-Admin/logs/*.txt
/MP-Admin/bin/*
/MP-Admin/obj/*
/MP-ADM/logs/*.zip
/MP-ADM/logs/*.txt
/MP-ADM/bin/*
/MP-ADM/obj/*
#--------------------------------
# Area ES3
#--------------------------------
/ES3/logs/*.zip
/ES3/logs/*.txt
/ES3/bin/*
/ES3/obj/*
#--------------------------------
# Area MoonProTablet
#--------------------------------
/MP-TAB/logs/*.zip
/MP-TAB/logs/*.txt
/MP-TAB/bin/*
/MP-TAB/obj/*
/MP-TAB/WebCharts/*.png
/MP-TAB/images/macchine/*.*
!/MP-TAB/images/macchine/Steamware.png
/MP-TAB/Files/Disegni/*.pdf
!/MP-TAB/Files/Disegni/ND.pdf
MP-TAB/logs/
#--------------------------------
# Area MoonPro
#--------------------------------
/MP-Site/logs/*.zip
/MP-Site/logs/*.txt
/MP-Site/bin/*
/MP-Site/obj/*
/MP-Site/WebCharts/*.png
/MP-Site/images/macchine/*.*
!/MP-Site/images/macchine/Steamware.png
# ---> VisualStudio
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
@@ -429,3 +345,4 @@ _UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
MP.Prog/Shared/MainLayout.razor
+51 -20
View File
@@ -1,22 +1,22 @@
variables:
# NUGET_PATH: 'C:\Tools\nuget.exe'
# MSBUILD_PATH: 'C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\Current\Bin\MSBuild.exe'
# 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'
# NEW_REL: ''
VERS_MAIN: '1.0'
NEXUS_PATH: 'MP-STATS'
APP_NAME: 'MP.Stats'
NUGET_PATH: 'C:\Tools\nuget.exe'
MSBUILD_PATH: 'C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\Current\Bin\MSBuild.exe'
ASPNET_MERGE_PATH: 'C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools'
EXE_RELEASE_FOLDER: 'c:\Projetcs\Compiled\MP-CORE\Release'
DEPLOY_FOLDER: 'c:\Projects\Deploy\MP-CORE\Builds'
VERS_MAIN: '1.1'
# VERS_FULL: '0.0.0.0'
NEXUS_PATH: 'MP-STATS'
APP_NAME: 'MP.Stats'
# helper x fix pacchetti nuget da repo locale nexus.steamware.net
.nuget-fix: &nuget-fix
- |
$hasSource = C:\Tools\nuget.exe sources list | find "`"Steamware Nexus`"" /C
if ($hasSource -eq 0) {
C:\Tools\nuget.exe sources Add -Name "`"Steamware Nexus`"" -Source http://nexus.steamware.net/repository/nuget-group -username "`"nugetUser`"" -password "`"viaDante16`""
C:\Tools\nuget.exe sources Add -Name "`"Steamware Nexus`"" -Source https://nexus.steamware.net/repository/nuget-group -username "`"nugetUser`"" -password "`"viaDante16`""
} else {
C:\Tools\nuget.exe sources Update -Name "`"Steamware Nexus`"" -Source http://nexus.steamware.net/repository/nuget-group -username "`"nugetUser`"" -password "`"viaDante16`""
C:\Tools\nuget.exe sources Update -Name "`"Steamware Nexus`"" -Source https://nexus.steamware.net/repository/nuget-group -username "`"nugetUser`"" -password "`"viaDante16`""
}
echo $hasSource
@@ -39,7 +39,8 @@ variables:
Set-Alias mCurl C:\Windows\system32\curl.exe
$currentDate = get-date -format yyMM;
$currentTime = get-date -format ddHH;
$VersNumb = Get-Content "Resources\VersNum.txt"
$fileVers = $env:APP_NAME + "\Resources\VersNum.txt"
$VersNumb = Get-Content $fileVers
echo "Curr Version: $VersNumb"
if($CI_COMMIT_BRANCH -eq "master")
{
@@ -52,11 +53,11 @@ variables:
$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 $File https://nexus.steamware.net/repository/SWS/$env:NEXUS_PATH/$version/0/$FileName
mCurl -v -u GitLab:$NEXUS_PASSWD --upload-file $File https://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 GitLab:$NEXUS_PASSWD --upload-file "$env:APP_NAME\Resources\manifest.xml" https://nexus.steamware.net/repository/SWS/$env:NEXUS_PATH/$version/0/manifest.xml
mCurl -v -u GitLab:$NEXUS_PASSWD --upload-file "$env:APP_NAME\Resources\ChangeLog.html" https://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
@@ -74,9 +75,11 @@ build:
- win
before_script:
- *nuget-fix
- dotnet restore
- dotnet restore MP-STATS.sln
- dotnet restore MP-PROG.sln
script:
- dotnet build
- dotnet build MP.Stats/MP.Stats.csproj
- dotnet build MP.Prog/MP.Prog.csproj
test:
stage: test
@@ -86,7 +89,8 @@ test:
- develop
needs: ["build"]
script:
- dotnet test
- dotnet test MP.Stats/MP.Stats.csproj
- dotnet test MP.Prog/MP.Prog.csproj
IIS01:deploy:
stage: deploy
@@ -100,6 +104,7 @@ IIS01:deploy:
# - dotnet restore
script:
- 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
- dotnet publish -p:PublishProfile=IIS01.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=viadante16 -p:AllowUntrustedCertificate=true MP.Prog/MP.Prog.csproj
IIS02:deploy:
@@ -115,8 +120,10 @@ IIS02:deploy:
script:
- 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
- dotnet publish -p:PublishProfile=IIS02.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=viadante16 -p:AllowUntrustedCertificate=true MP.Prog/MP.Prog.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.Prog/MP.Prog.csproj
installer:
STA:installer:
stage: installer
tags:
- win
@@ -124,6 +131,9 @@ installer:
- develop
- master
needs: ["build"]
variables:
APP_NAME: MP.Stats
NEXUS_PATH: MP-STATS
before_script:
# - *nuget-fix
# - dotnet restore
@@ -132,6 +142,26 @@ installer:
# qui il deploy su nexus...
- *hashBuild
- *nexusUpload
PRG:installer:
stage: installer
tags:
- win
only:
- develop
- master
needs: ["build"]
variables:
APP_NAME: MP.Prog
NEXUS_PATH: MP-PROG
before_script:
# - *nuget-fix
# - dotnet restore
script:
- dotnet publish -p:PublishProfile=IISProfile.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release MP.Prog/MP.Prog.csproj -o:publish
# qui il deploy su nexus...
- *hashBuild
- *nexusUpload
release:
stage: release
@@ -149,5 +179,6 @@ release:
- publish/
script:
- dotnet publish -c Release -o ./publish MP.Stats/MP.Stats.csproj
- dotnet publish -c Release -o ./publish MP.Prog/MP.Prog.csproj
+31
View File
@@ -0,0 +1,31 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.31229.75
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MP.Prog", "MP.Prog\MP.Prog.csproj", "{3223DDE4-564E-4D58-8A94-E368B9778C67}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MP.FileData", "MP.FileData\MP.FileData.csproj", "{48693321-1FA6-4DBB-A730-B8EF3E0B68D2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{3223DDE4-564E-4D58-8A94-E368B9778C67}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3223DDE4-564E-4D58-8A94-E368B9778C67}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3223DDE4-564E-4D58-8A94-E368B9778C67}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3223DDE4-564E-4D58-8A94-E368B9778C67}.Release|Any CPU.Build.0 = Release|Any CPU
{48693321-1FA6-4DBB-A730-B8EF3E0B68D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{48693321-1FA6-4DBB-A730-B8EF3E0B68D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{48693321-1FA6-4DBB-A730-B8EF3E0B68D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{48693321-1FA6-4DBB-A730-B8EF3E0B68D2}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {632D11D1-088B-4795-97E5-048534002558}
EndGlobalSection
EndGlobal
-12
View File
@@ -1,12 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MP.Data
{
class Constants
{
}
}
-8
View File
@@ -1,8 +0,0 @@
using System;
namespace MP.Data
{
public class Enums
{
}
}
+5 -5
View File
@@ -12,14 +12,14 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="5.0.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="5.0.6">
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.10" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="5.0.10" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.10" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="5.0.10">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="5.0.1" />
<PackageReference Include="NLog" Version="4.7.10" />
<PackageReference Include="NLog" Version="4.7.11" />
</ItemGroup>
</Project>
-12
View File
@@ -1,12 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MP.Data
{
public class StatsDbContext
{
}
}
File diff suppressed because it is too large Load Diff
+47
View File
@@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MP.FileData.DTO
{
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
public class ArchiveStatusDTO
{
/// <summary>
/// Idx macchina
/// </summary>
public string IdxMacchina { get; set; } = "";
/// <summary>
/// Nome macchina
/// </summary>
public string Nome { get; set; } = "";
/// <summary>
/// Descrizione macchina
/// </summary>
public string Descrizione { get; set; } = "";
/// <summary>
/// Percorso base x macchina
/// </summary>
public string BasePath { get; set; } = "";
/// <summary>
/// Totale file della amcchina
/// </summary>
public int TotFile { get; set; } = 0;
/// <summary>
/// NBumero file modificati da confermare/rifiutare
/// </summary>
public int NumChanged { get; set; } = 0;
/// <summary>
/// Conteggio totale tags x macchina
/// </summary>
public int TotalTags { get; set; }
/// <summary>
/// Numero di file SENZA tag
/// </summary>
public int NoTags { get; set; }
}
}
+60
View File
@@ -0,0 +1,60 @@
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
namespace MP.FileData.DatabaseModels
{
/// <summary>
/// Tabella archivio dei File Programma
/// </summary>
[Table("Files")]
[Index(nameof(IdxMacchina), nameof(Active), nameof(DiskStatus))]
public partial class FileModel
{
#region Public Properties
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int FileId { get; set; }
public bool Active { get; set; } = true;
public string IdxMacchina { get; set; } = "";
public string Name { get; set; } = "";
public int Rev { get; set; } = 0;
public DateTime LastMod { get; set; }
public long Size { get; set; } = 0;
public string Path { get; set; } = "";
public string MimeType { get; set; } = "";
public string MD5 { get; set; } = "";
public FileState DiskStatus { get; set; } = FileState.Ok;
public DateTime LastCheck { get; set; } = DateTime.Now.AddYears(-1);
public byte[] FileContent { get; set; }
public ICollection<TagModel> Tags { get; set; }
[NotMapped]
public string FileStringContent
{
get
{
return Encoding.UTF8.GetString(FileContent);
}
set
{
// serializzo a byte
FileContent = Encoding.ASCII.GetBytes(value);
}
}
[ForeignKey("IdxMacchina")]
public virtual MacchinaModel Macchina { get; set; }
#endregion Public Properties
}
}
@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
namespace MP.FileData.DatabaseModels
{
[Table("Macchine")]
public partial class MacchinaModel
{
#region Public Properties
[Key]
public string IdxMacchina { get; set; } = "";
public string RuleName { get; set; } = "";
public string Nome { get; set; } = "";
public string Descrizione { get; set; } = "";
public string BasePath { get; set; } = "";
public string ImgUrl { get; set; } = "";
public string Note { get; set; } = "";
public int ShowOrder { get; set; } = 999;
#endregion Public Properties
}
}
+23
View File
@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
namespace MP.FileData.DatabaseModels
{
[Table("Tags")]
public partial class TagModel
{
[Key]
public string TagId { get; set; }
public ICollection<FileModel> Files { get; set; }
}
}
+19
View File
@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MP.FileData
{
/// <summary>
/// Stato File
/// </summary>
public enum FileState
{
ND = 0,
Changed,
Deleted,
Ok
}
}
+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.FileData
{
public class FileUtils
{
#region Public Methods
/// <summary>
/// Elenco dei file data la directory da controllare
/// </summary>
/// <param name="path"></param>
/// <param name="searchPattern"></param>
/// <returns></returns>
public static FileInfo[] GetFileList(string path, string searchPattern)
{
//string[] answ = Directory.GetFiles(path, searchPattern);
DriveInfo di = new DriveInfo(path);
DirectoryInfo dirInfo = di.RootDirectory;
FileInfo[] answ = dirInfo.GetFiles("*.*");
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
}
}
+27
View File
@@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.9">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="5.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="5.0.9">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="5.0.1" />
<PackageReference Include="NLog" Version="4.7.11" />
</ItemGroup>
<ItemGroup>
<Folder Include="Migrations\" />
</ItemGroup>
</Project>
+170
View File
@@ -0,0 +1,170 @@
// <auto-generated />
using System;
using MP.FileData;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace MP.FileData.Migrations
{
[DbContext(typeof(MoonPro_ProgContext))]
[Migration("20210913153816_InitDb")]
partial class InitDb
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("Relational:Collation", "SQL_Latin1_General_CP1_CI_AS")
.HasAnnotation("Relational:MaxIdentifierLength", 128)
.HasAnnotation("ProductVersion", "5.0.9")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
modelBuilder.Entity("FileModelTagModel", b =>
{
b.Property<int>("FilesFileId")
.HasColumnType("int");
b.Property<string>("TagsTagId")
.HasColumnType("nvarchar(450)");
b.HasKey("FilesFileId", "TagsTagId");
b.HasIndex("TagsTagId");
b.ToTable("FileModelTagModel");
});
modelBuilder.Entity("MP.FileData.DatabaseModels.FileModel", b =>
{
b.Property<int>("FileId")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<bool>("Active")
.HasColumnType("bit");
b.Property<int>("DiskStatus")
.HasColumnType("int");
b.Property<byte[]>("FileContent")
.HasColumnType("varbinary(max)");
b.Property<string>("IdxMacchina")
.HasColumnType("nvarchar(450)");
b.Property<DateTime>("LastCheck")
.HasColumnType("datetime2");
b.Property<DateTime>("LastMod")
.HasColumnType("datetime2");
b.Property<string>("MD5")
.HasColumnType("nvarchar(max)");
b.Property<string>("MimeType")
.HasColumnType("nvarchar(max)");
b.Property<string>("Name")
.HasColumnType("nvarchar(max)");
b.Property<string>("Path")
.HasColumnType("nvarchar(max)");
b.Property<int>("Rev")
.HasColumnType("int");
b.Property<long>("Size")
.HasColumnType("bigint");
b.HasKey("FileId");
b.HasIndex("IdxMacchina", "Active", "DiskStatus");
b.ToTable("Files");
});
modelBuilder.Entity("MP.FileData.DatabaseModels.MacchinaModel", b =>
{
b.Property<string>("IdxMacchina")
.HasColumnType("nvarchar(450)");
b.Property<string>("BasePath")
.HasColumnType("nvarchar(max)");
b.Property<string>("Descrizione")
.HasColumnType("nvarchar(max)");
b.Property<string>("ImgUrl")
.HasColumnType("nvarchar(max)");
b.Property<string>("Nome")
.HasColumnType("nvarchar(max)");
b.Property<string>("Note")
.HasColumnType("nvarchar(max)");
b.Property<string>("RuleName")
.HasColumnType("nvarchar(max)");
b.Property<int>("ShowOrder")
.HasColumnType("int");
b.HasKey("IdxMacchina");
b.ToTable("Macchine");
b.HasData(
new
{
IdxMacchina = "0",
BasePath = "",
Descrizione = "--- Tutte ---",
ImgUrl = "",
Nome = "--- Tutte ---",
Note = "",
RuleName = "0",
ShowOrder = 0
});
});
modelBuilder.Entity("MP.FileData.DatabaseModels.TagModel", b =>
{
b.Property<string>("TagId")
.HasColumnType("nvarchar(450)");
b.HasKey("TagId");
b.ToTable("Tags");
});
modelBuilder.Entity("FileModelTagModel", b =>
{
b.HasOne("MP.FileData.DatabaseModels.FileModel", null)
.WithMany()
.HasForeignKey("FilesFileId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MP.FileData.DatabaseModels.TagModel", null)
.WithMany()
.HasForeignKey("TagsTagId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("MP.FileData.DatabaseModels.FileModel", b =>
{
b.HasOne("MP.FileData.DatabaseModels.MacchinaModel", "Macchina")
.WithMany()
.HasForeignKey("IdxMacchina");
b.Navigation("Macchina");
});
#pragma warning restore 612, 618
}
}
}
@@ -0,0 +1,124 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
namespace MP.FileData.Migrations
{
public partial class InitDb : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Macchine",
columns: table => new
{
IdxMacchina = table.Column<string>(type: "nvarchar(450)", nullable: false),
RuleName = table.Column<string>(type: "nvarchar(max)", nullable: true),
Nome = table.Column<string>(type: "nvarchar(max)", nullable: true),
Descrizione = table.Column<string>(type: "nvarchar(max)", nullable: true),
BasePath = table.Column<string>(type: "nvarchar(max)", nullable: true),
ImgUrl = table.Column<string>(type: "nvarchar(max)", nullable: true),
Note = table.Column<string>(type: "nvarchar(max)", nullable: true),
ShowOrder = table.Column<int>(type: "int", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Macchine", x => x.IdxMacchina);
});
migrationBuilder.CreateTable(
name: "Tags",
columns: table => new
{
TagId = table.Column<string>(type: "nvarchar(450)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Tags", x => x.TagId);
});
migrationBuilder.CreateTable(
name: "Files",
columns: table => new
{
FileId = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
Active = table.Column<bool>(type: "bit", nullable: false),
IdxMacchina = table.Column<string>(type: "nvarchar(450)", nullable: true),
Name = table.Column<string>(type: "nvarchar(max)", nullable: true),
Rev = table.Column<int>(type: "int", nullable: false),
LastMod = table.Column<DateTime>(type: "datetime2", nullable: false),
Size = table.Column<long>(type: "bigint", nullable: false),
Path = table.Column<string>(type: "nvarchar(max)", nullable: true),
MimeType = table.Column<string>(type: "nvarchar(max)", nullable: true),
MD5 = table.Column<string>(type: "nvarchar(max)", nullable: true),
DiskStatus = table.Column<int>(type: "int", nullable: false),
LastCheck = table.Column<DateTime>(type: "datetime2", nullable: false),
FileContent = table.Column<byte[]>(type: "varbinary(max)", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Files", x => x.FileId);
table.ForeignKey(
name: "FK_Files_Macchine_IdxMacchina",
column: x => x.IdxMacchina,
principalTable: "Macchine",
principalColumn: "IdxMacchina",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "FileModelTagModel",
columns: table => new
{
FilesFileId = table.Column<int>(type: "int", nullable: false),
TagsTagId = table.Column<string>(type: "nvarchar(450)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_FileModelTagModel", x => new { x.FilesFileId, x.TagsTagId });
table.ForeignKey(
name: "FK_FileModelTagModel_Files_FilesFileId",
column: x => x.FilesFileId,
principalTable: "Files",
principalColumn: "FileId",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_FileModelTagModel_Tags_TagsTagId",
column: x => x.TagsTagId,
principalTable: "Tags",
principalColumn: "TagId",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.InsertData(
table: "Macchine",
columns: new[] { "IdxMacchina", "BasePath", "Descrizione", "ImgUrl", "Nome", "Note", "RuleName", "ShowOrder" },
values: new object[] { "0", "", "--- Tutte ---", "", "--- Tutte ---", "", "0", 0 });
migrationBuilder.CreateIndex(
name: "IX_FileModelTagModel_TagsTagId",
table: "FileModelTagModel",
column: "TagsTagId");
migrationBuilder.CreateIndex(
name: "IX_Files_IdxMacchina_Active_DiskStatus",
table: "Files",
columns: new[] { "IdxMacchina", "Active", "DiskStatus" });
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "FileModelTagModel");
migrationBuilder.DropTable(
name: "Files");
migrationBuilder.DropTable(
name: "Tags");
migrationBuilder.DropTable(
name: "Macchine");
}
}
}
@@ -0,0 +1,168 @@
// <auto-generated />
using System;
using MP.FileData;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace MP.FileData.Migrations
{
[DbContext(typeof(MoonPro_ProgContext))]
partial class MoonPro_ProgContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("Relational:Collation", "SQL_Latin1_General_CP1_CI_AS")
.HasAnnotation("Relational:MaxIdentifierLength", 128)
.HasAnnotation("ProductVersion", "5.0.9")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
modelBuilder.Entity("FileModelTagModel", b =>
{
b.Property<int>("FilesFileId")
.HasColumnType("int");
b.Property<string>("TagsTagId")
.HasColumnType("nvarchar(450)");
b.HasKey("FilesFileId", "TagsTagId");
b.HasIndex("TagsTagId");
b.ToTable("FileModelTagModel");
});
modelBuilder.Entity("MP.FileData.DatabaseModels.FileModel", b =>
{
b.Property<int>("FileId")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<bool>("Active")
.HasColumnType("bit");
b.Property<int>("DiskStatus")
.HasColumnType("int");
b.Property<byte[]>("FileContent")
.HasColumnType("varbinary(max)");
b.Property<string>("IdxMacchina")
.HasColumnType("nvarchar(450)");
b.Property<DateTime>("LastCheck")
.HasColumnType("datetime2");
b.Property<DateTime>("LastMod")
.HasColumnType("datetime2");
b.Property<string>("MD5")
.HasColumnType("nvarchar(max)");
b.Property<string>("MimeType")
.HasColumnType("nvarchar(max)");
b.Property<string>("Name")
.HasColumnType("nvarchar(max)");
b.Property<string>("Path")
.HasColumnType("nvarchar(max)");
b.Property<int>("Rev")
.HasColumnType("int");
b.Property<long>("Size")
.HasColumnType("bigint");
b.HasKey("FileId");
b.HasIndex("IdxMacchina", "Active", "DiskStatus");
b.ToTable("Files");
});
modelBuilder.Entity("MP.FileData.DatabaseModels.MacchinaModel", b =>
{
b.Property<string>("IdxMacchina")
.HasColumnType("nvarchar(450)");
b.Property<string>("BasePath")
.HasColumnType("nvarchar(max)");
b.Property<string>("Descrizione")
.HasColumnType("nvarchar(max)");
b.Property<string>("ImgUrl")
.HasColumnType("nvarchar(max)");
b.Property<string>("Nome")
.HasColumnType("nvarchar(max)");
b.Property<string>("Note")
.HasColumnType("nvarchar(max)");
b.Property<string>("RuleName")
.HasColumnType("nvarchar(max)");
b.Property<int>("ShowOrder")
.HasColumnType("int");
b.HasKey("IdxMacchina");
b.ToTable("Macchine");
b.HasData(
new
{
IdxMacchina = "0",
BasePath = "",
Descrizione = "--- Tutte ---",
ImgUrl = "",
Nome = "--- Tutte ---",
Note = "",
RuleName = "0",
ShowOrder = 0
});
});
modelBuilder.Entity("MP.FileData.DatabaseModels.TagModel", b =>
{
b.Property<string>("TagId")
.HasColumnType("nvarchar(450)");
b.HasKey("TagId");
b.ToTable("Tags");
});
modelBuilder.Entity("FileModelTagModel", b =>
{
b.HasOne("MP.FileData.DatabaseModels.FileModel", null)
.WithMany()
.HasForeignKey("FilesFileId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MP.FileData.DatabaseModels.TagModel", null)
.WithMany()
.HasForeignKey("TagsTagId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("MP.FileData.DatabaseModels.FileModel", b =>
{
b.HasOne("MP.FileData.DatabaseModels.MacchinaModel", "Macchina")
.WithMany()
.HasForeignKey("IdxMacchina");
b.Navigation("Macchina");
});
#pragma warning restore 612, 618
}
}
}
+29
View File
@@ -0,0 +1,29 @@
using Microsoft.EntityFrameworkCore;
using MP.FileData.DatabaseModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MP.FileData
{
public static class ModelBuilderExtensions
{
#region Public Methods
/// <summary>
/// Estensione per seed iniziale dei dati nel DB
/// </summary>
/// <param name="modelBuilder"></param>
public static void Seed(this ModelBuilder modelBuilder)
{
// inizializzazione dei valori di default x MACCHINA
modelBuilder.Entity<MacchinaModel>().HasData(
new MacchinaModel { IdxMacchina = "0", RuleName = "0", Descrizione = "--- Tutte ---", Nome = "--- Tutte ---", BasePath = "", ImgUrl = "", Note = "", ShowOrder = 0 }
);
}
#endregion Public Methods
}
}
+104
View File
@@ -0,0 +1,104 @@
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.Extensions.Configuration;
using MP.FileData.DatabaseModels;
using NLog;
namespace MP.FileData
{
public partial class MoonPro_ProgContext : DbContext
{
#region Private Fields
private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
private IConfiguration _configuration;
#endregion Private Fields
#region Public Constructors
[Obsolete("This constructor should never be used directly, and is only needed to generate entityframework stuff. Connection string can be adapted as pleased.")]
public MoonPro_ProgContext()
{
}
public MoonPro_ProgContext(IConfiguration configuration)
{
_configuration = configuration;
try
{
// se non ci fosse... crea o migra!
Database.Migrate();
}
catch (Exception exc)
{
Log.Error(exc, "Exception during context initialization 01");
}
}
public MoonPro_ProgContext(DbContextOptions<MoonPro_ProgContext> options) : base(options)
{
try
{
// se non ci fosse... crea o migra!
Database.Migrate();
}
catch (Exception exc)
{
Log.Error(exc, "Exception during context initialization 02");
}
}
#endregion Public Constructors
#region Public Properties
public virtual DbSet<MacchinaModel> DbSetMacchine { get; set; }
public virtual DbSet<FileModel> DbSetProgFile { get; set; }
public virtual DbSet<TagModel> DbSetTags { get; set; }
#endregion Public Properties
#region Private Methods
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
#endregion Private Methods
#region Protected Methods
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
string connString = _configuration.GetConnectionString("Mp.Prog");
if (!string.IsNullOrEmpty(connString))
{
optionsBuilder.UseSqlServer(connString);
}
else
{
optionsBuilder.UseSqlServer("Server=SQL2016DEV;Database=MoonPro_PROG;Trusted_Connection=True;");
}
}
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.HasAnnotation("Relational:Collation", "SQL_Latin1_General_CP1_CI_AS");
//
modelBuilder.Seed();
OnModelCreatingPartial(modelBuilder);
}
#endregion Protected Methods
}
}
+83
View File
@@ -0,0 +1,83 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MP.FileData
{
public enum SearchMode
{
/// <summary>
/// Ricerca occorrenze di una RegExp dentro il contenuto del file
/// </summary>
StringOnFile,
/// <summary>
/// Cerca da path relativo + nome file
/// </summary>
PathAndName
}
public class SearchRules
{
#region Public Properties
/// <summary>
/// Estensioni file esclusi
/// </summary>
public List<string> ExcludedFileExt { get; set; } = new List<string>();
/// <summary>
/// Pattern esclusione Tags (stop-words)
/// </summary>
public List<string> ExcludedTags { get; set; } = new List<string>();
/// <summary>
/// Pattern in formato RegExp
/// </summary>
public Dictionary<string, string> FileNameExtReplace { get; set; } = new Dictionary<string, string>();
/// <summary>
/// Quantità massima di caratteri da analizzare, 0 = tutti
/// </summary>
public int MaxChar2Search { get; set; } = 100;
/// <summary>
/// Modalità ricerca
/// </summary>
public SearchMode Mode { get; set; } = SearchMode.StringOnFile;
/// <summary>
/// Nome della regola di ricerca
/// </summary>
public string Name { get; set; } = "ND";
/// <summary>
/// Configurazione opzionale x rimozione filename da output finali
/// </summary>
public bool OutExcludeFileName { get; set; } = true;
/// <summary>
/// Replace in uscita per "bonificare" il tag
/// </summary>
public Dictionary<string, string> OutReplace { get; set; } = new Dictionary<string, string>();
/// <summary>
/// Pattern in formato RegExp
/// </summary>
public string RegExPattern { get; set; } = "";
/// <summary>
/// Configurazione opzionale x sostituzione placeholder {{fileName}} in RegExp con il VERO nome file
/// </summary>
public bool RegExRepFileName { get; set; } = true;
/// <summary>
/// Configurazione opzionale x sostituzione carriage return --> spazi
/// </summary>
public bool ReplaceCR { get; set; } = true;
#endregion Public Properties
}
}
+158
View File
@@ -0,0 +1,158 @@
using NLog;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace MP.FileData
{
/// <summary>
/// Helper estrazione tag x programmi
/// </summary>
public class TagsUtils
{
#region Private Fields
private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
#endregion Private Fields
#region Protected Fields
protected static List<string> ExcludeTags = new List<string>();
#endregion Protected Fields
#region Public Methods
/// <summary>
/// Cerca tag a aprtire da directory + nome file, ignorando delle stopword
///
/// es: ...\BUSSOLE.WPD\172L_EST8.MPF --> "BUSSOLE", "172L_EST8"
/// </summary>
/// <param name="filePath">Nome del file (path completo)</param>
/// <param name="currRule">Parametri analisi</param>
/// <returns></returns>
public static List<string> searchPathName(string filePath, string basePath, SearchRules currRule)
{
List<string> answ = new List<string>();
string fileName = Path.GetFileName(filePath);
#if false
// dal nome se richeisto estraggo...
if (!currRule.OutExcludeFileName)
{
// bonifico
foreach (var item in currRule.OutReplace)
{
fileName = fileName.Replace(item.Key, item.Value);
}
// aggiungo fileName
answ.Add(fileName);
}
#endif
// ora da path... escludo base e file...
string dirPath = filePath.Replace(basePath, "");
// bonifico
foreach (var item in currRule.OutReplace)
{
dirPath = dirPath.Replace(item.Key, item.Value);
}
// splitto per "/"
var pathTags = dirPath.Split(@"\");
foreach (var item in pathTags)
{
if (!string.IsNullOrWhiteSpace(item))
{
// fix replace filtro
answ.Add(item);
}
}
// se nullo --> segnalo!
if (answ.Count == 0)
{
Log.Warn($"searchPathName Attenzione Tag non trovati | {filePath} | basePath: {basePath}");
}
return answ;
}
/// <summary>
/// Cerca tag di commento inseriti nel formato
/// NOME_PROG(commento)
///
/// es: O00123(172L D20.5) --> estrae 172L, D20.5
/// </summary>
/// <param name="fileName">Nome del file (da cercare per contenuto)</param>
/// <param name="fileContent">Contenuto del file da analizzare</param>
/// <param name="currRule">Parametri analisi</param>
/// <returns></returns>
public static List<string> searchProgComment(string fileName, string fileContent, SearchRules currRule)
{
// verifico se trimmare contenuto file
if (fileContent.Length > currRule.MaxChar2Search && currRule.MaxChar2Search > 0)
{
fileContent = fileContent.Substring(0, currRule.MaxChar2Search);
}
// bonifico: a capo --> spazi
fileContent = fileContent.Replace(Environment.NewLine, " ").ToUpper();
//string pattern = $"\\b{fileName}" + @".{0,2}\([\w\d\s.]+\)";
string pattern = currRule.RegExPattern;
if (currRule.RegExRepFileName)
{
pattern = pattern.Replace("{{fileName}}", fileName);
}
List<string> answ = new List<string>();
if (fileContent.Length > 0)
{
// uso regexp
MatchCollection matchTags = Regex.Matches(fileContent, pattern);
if (matchTags.Count > 0)
{
for (int count = 0; count < matchTags.Count; count++)
{
string currMatch = matchTags[count].Value;
// bonifica preliminare (se richiesta)
if (currRule.OutExcludeFileName)
{
currMatch = currMatch.Replace(fileName, "");
}
if (currRule.OutReplace.Count > 0)
{
foreach (var item in currRule.OutReplace)
{
currMatch = currMatch.Replace(item.Key, item.Value);
}
}
// trim finale
currMatch = currMatch.Trim();
// split con spazi
var splitTags = currMatch.Split(" ");
foreach (var item in splitTags)
{
if (!string.IsNullOrEmpty(item))
{
if (!currRule.ExcludedTags.Contains(item) && item != fileName)
{
// esclusione valori ignorati
answ.Add(item);
}
}
}
}
}
}
// se nullo --> segnalo!
if (answ.Count == 0)
{
Log.Warn($"searchProgComment Attenzione Tag non trovati | {fileName} | pattern: {pattern}{Environment.NewLine}{fileContent}");
}
return answ;
}
#endregion Public Methods
}
}
+5
View File
@@ -0,0 +1,5 @@
{
"version": 1,
"isRoot": true,
"tools": {}
}
+10
View File
@@ -0,0 +1,10 @@
<Router AppAssembly="@typeof(Program).Assembly" PreferExactMatches="@true">
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
</Found>
<NotFound>
<LayoutView Layout="@typeof(MainLayout)">
<p>Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
+99
View File
@@ -0,0 +1,99 @@
<div class="row">
<div class="col-4">
<button id="btnForceCheck" class="btn btn-primary btn-sm btn-block" @onclick="() => ForceCheck(0)" title="Forza verifica archivio (totale)">
<i class="fas fa-sync-alt"></i> Update Completo Archivio <i class="far fa-folder-open"></i>
</button>
</div>
<div class="col-8 py-2">
@if (showProgress)
{
<div class="progress">
<div class="progress-bar progress-bar-striped progress-bar-animated" style="width:@percLoading%;"></div>
</div>
}
</div>
<div class="col-12 mt-2">
@if (ListRecords == null)
{
<div class="row">
<div class="col-4">
@if (showProgress)
{
<div class="col-12 mt-2">
<div class="alert alert-primary">
@if (setupMessages.Count > 0)
{
<ul>
@foreach (var item in setupMessages)
{
<li>@item</li>
}
</ul>
}
</div>
</div>
}
</div>
<div class="col-8">
<LoadingData></LoadingData>
</div>
</div>
}
else if (totalCount == 0)
{
<div class="alert alert-warning text-center display-4">Nessun record trovato</div>
}
else
{
<table class="table table-sm table-striped table-responsive-lg">
<thead>
<tr>
<th></th>
<th>Macchina</th>
<th>Path</th>
<th class="text-right">Tags</th>
<th class="text-right">Senza Tag</th>
<th class="text-right">Modificati</th>
<th class="text-right">Tot File</th>
</tr>
</thead>
<tbody>
@foreach (var record in ListRecords)
{
<tr>
<td>
@if (!string.IsNullOrEmpty(record.BasePath))
{
<button id="btnForceCheck" class="btn btn-warning btn-sm" @onclick="() => ForceCheckMacchina(record.IdxMacchina)" title="Forza verifica Archivio singola macchina">
<i class="fas fa-sync-alt"></i>
</button>
}
</td>
<td>
@record.Nome
</td>
<td>
<div class="small">@record.BasePath</div>
</td>
<td class="text-right">
@record.TotalTags
</td>
<td class="text-right">
@record.NoTags
</td>
<td class="text-right">
@record.NumChanged
</td>
<td class="text-right">
<b>
@record.TotFile
</b>
</td>
</tr>
}
</tbody>
</table>
}
</div>
</div>
+133
View File
@@ -0,0 +1,133 @@
using Microsoft.AspNetCore.Components;
using MP.FileData.DTO;
using MP.Prog.Data;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace MP.Prog.Components
{
public partial class ArchiveStatus
{
#region Private Fields
private List<ArchiveStatusDTO> ListRecords;
private int numChecks = 0;
private int totalCount = 0;
#endregion Private Fields
#region Private Properties
private List<string> setupMessages { get; set; } = new List<string>();
#endregion Private Properties
#region Protected Properties
[Inject]
protected FileArchDataService DataService { get; set; }
protected int percLoading { get; set; } = 0;
protected bool showProgress { get; set; } = false;
#endregion Protected Properties
#region Private Methods
private async Task verificaSingola(string idxMacchina, int numDays, int numMacchine)
{
// recupero elenco macchine
percLoading += 100 / numMacchine;
numChecks = await DataService.updateMachineArchive(idxMacchina, numDays, true, false);
await Task.Delay(1);
setupMessages.Add($"{idxMacchina}: {numChecks} files");
StateHasChanged();
await Task.Delay(1);
}
private async Task verificaTutte(int numDays)
{
// recupero elenco macchine
var listaMacchine = await DataService.MacchineGetAll();
int numMacchine = listaMacchine.Count();
foreach (var item in listaMacchine.Where(x => !string.IsNullOrEmpty(x.BasePath)).ToList())
{
await verificaSingola(item.IdxMacchina, numDays, numMacchine);
}
}
#endregion Private Methods
#region Protected Methods
protected async Task ArchiveCheck(int maxHour)
{
showProgress = true;
percLoading = 0;
await verificaTutte(maxHour);
setupMessages.Add($"Effettuata verifica e rilettura di {numChecks} files!");
await ReloadData();
}
protected async Task ArchiveSingleCheck(string idxMacchina, int maxHour)
{
showProgress = true;
percLoading = 0;
await verificaSingola(idxMacchina, maxHour, 2);
setupMessages.Add($"Effettuata verifica e rilettura di {numChecks} files!");
await ReloadData();
}
protected async Task ClearMessage()
{
await Task.Delay(10);
setupMessages = new List<string>();
}
protected async Task ForceCheck(int maxHour)
{
setupMessages.Add("Inizio Analisi Archivio...");
ListRecords = null;
await Task.Delay(1);
await ArchiveCheck(maxHour);
await ClearMessage();
await ReloadData();
}
protected async Task ForceCheckMacchina(string idxMacchina)
{
setupMessages.Add("Inizio Analisi Archivio...");
ListRecords = null;
await Task.Delay(1);
await ArchiveSingleCheck(idxMacchina, 0);
await ClearMessage();
await ReloadData();
}
protected override async Task OnInitializedAsync()
{
ListRecords = null;
await ReloadData();
}
protected async Task ReloadData()
{
await Task.Delay(1);
numChecks = 0;
ListRecords = await DataService.GetArchiveStatus();
totalCount = ListRecords.Count;
await Task.Delay(1);
setupMessages = new List<string>();
showProgress = false;
percLoading = 0;
}
#endregion Protected Methods
}
}
+16
View File
@@ -0,0 +1,16 @@
<div class="form-row text-light">
<div class="col-5 pr-0 text-left">
MP.Prog <span class="small">v.@version</span>
</div>
<div class="col-7 pl-0 text-right">
<span class="small">@adesso</span>
<a class="text-light" href="https://www.egalware.com/" target="_blank">Egalware<img class="img-fluid" width="16" src="img/LogoBlu.svg" /></a>
</div>
</div>
@code {
protected DateTime adesso = DateTime.Now;
Version version = typeof(Program).Assembly.GetName().Version;
}
+84
View File
@@ -0,0 +1,84 @@
@using MP.Prog.Components
@using System.Security.Claims
@*@using Microsoft.AspNetCore.Components.Authorization*@
@using MP.Prog.Data
@inject MessageService AppMessages
@*@inject AuthenticationStateProvider AuthenticationStateProvider*@
<div class="form-row pt-3">
<div class="col-7 col-md-6 col-lg-4 col-xl-3">
@*<LoginDisplay></LoginDisplay>*@
@*<i class="fas fa-user-alt"></i> <b>@userName</b>*@
</div>
<div class="col-12 col-lg-4 col-xl-6 d-none d-lg-block text-center h4 text-truncate">
<span class="@PageIcon" aria-hidden="true"></span> @PageName
</div>
<div class="col-5 col-md-6 col-lg-4 col-xl-3 text-right">
@if (ShowSearch)
{
<SearchMod></SearchMod>
}
</div>
</div>
@code {
//[CascadingParameter]
//private Task<AuthenticationState> AuthenticationStateTask { get; set; }
[CascadingParameter(Name = "ShowSearch")]
private bool ShowSearch { get; set; }
private string userName = "";
private string PageName { get; set; }
private string PageIcon { get; set; }
protected override async Task OnInitializedAsync()
{
await forceReload();
}
protected override void OnInitialized()
{
AppMessages.EA_PageUpdated += OnPageUpdate;
}
public void OnPageUpdate()
{
PageName = AppMessages.PageName;
PageIcon = AppMessages.PageIcon;
InvokeAsync(() =>
{
StateHasChanged();
});
}
public void Dispose()
{
AppMessages.EA_PageUpdated -= OnPageUpdate;
}
private async Task forceReload()
{
userName = "N.A.";
await Task.Delay(1);
#if false
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
var user = authState.User;
if (user.Identity.IsAuthenticated)
{
userName = $"{user.Identity.Name}";
}
else
{
userName = "N.A.";
}
#endif
}
}
@* // Vedere anche:
// https://docs.microsoft.com/en-us/aspnet/core/blazor/security/?view=aspnetcore-5.0#:~:text=Blazor%20uses%20the%20existing%20ASP.NET%20Core%20authentication%20mechanisms,all%20client-side%20code%20can%20be%20modified%20by%20users
// https://docs.microsoft.com/en-us/aspnet/core/blazor/security/?view=aspnetcore-5.0*@
+110
View File
@@ -0,0 +1,110 @@
@using MP.FileData.DatabaseModels
@using MP.Prog.Data
@inject FileArchDataService DataService
@inject MessageService AppMService
@if (ArtList == null)
{
<LoadingData></LoadingData>
}
else
{
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text">
<span class="fas fa-search" aria-hidden="true"></span>
</span>
</div>
<input type="text" class="form-control form-control-sm" placeholder="Ricerca Articolo" @bind-value="@SearchArt" />
<select @bind="@SelCodArt" class="form-control form-control-sm">
@if (ArtList != null)
{
foreach (var item in ArtList)
{
<option value="@item.CodArticolo">@item.Disegno | @item.DescArticolo [@item.CodArticolo]</option>
}
}
</select>
<div class="input-group-append">
<button id="searchReset" class="btn btn-sm btn-secondary" @onclick="() => ResetSearchArt()" title="Reset ricerca articolo"><i class="fas fa-ban"></i></button>
</div>
</div>
}
@code {
[Parameter]
public EventCallback<string> searchUpdated { get; set; }
[Parameter]
public string SelCodArt
{
get
{
string answ = "";
if (AppMService.File_Filter != null)
{
answ = AppMService.File_Filter.CodArticolo;
}
return answ;
}
set
{
if (!AppMService.File_Filter.CodArticolo.Equals(value))
{
AppMService.File_Filter.CodArticolo = value;
}
reportChange();
}
}
private void reportChange()
{
searchUpdated.InvokeAsync(SelCodArt);
}
protected string _SearchArt;
protected string defCodArt = "";
protected List<ArticoloModel> ArtList;
protected string SearchArt
{
get
{
return _SearchArt;
}
set
{
_SearchArt = value;
// se son > 3 char... debounce...
if (string.IsNullOrEmpty(value))
{
_SearchArt = defCodArt;
}
if (value.Length >= defCodArt.Length)
{
var pUpd = Task.Run(async () =>
{
ArtList = await DataService.ArticoliGetFilt(SearchArt);
});
pUpd.Wait();
}
}
}
protected override async Task OnInitializedAsync()
{
await ReloadAllData();
_SearchArt = defCodArt;
}
protected async Task ReloadAllData()
{
SelCodArt = defCodArt;
ArtList = await DataService.ArticoliGetFilt(SearchArt);
}
protected void ResetSearchArt()
{
SearchArt = defCodArt;
}
}
+56
View File
@@ -0,0 +1,56 @@
<div class="row">
<div class="col-12 col-lg-9 text-left">
<div class="row">
<div class="col-12 small">
@if (totalCount > 0)
{
<ul class="pagination pagination-sm mb-1">
<li class="page-item"><button class="page-link" @onclick="() => PaginationItemClick(1)"><i class="fas fa-angle-double-left"></i></button></li>
<li class="page-item"><button class="page-link" @onclick="() => PaginationItemClick(prevBlock)"><i class="fas fa-angle-left"></i></button></li>
@for (int i = @startPage; i <= endPage; ++i)
{
var pageNum = i;
<li class="page-item @cssActive(pageNum)"><button class="page-link" @onclick="() => PaginationItemClick(pageNum)">@pageNum</button></li>
}
<li class="page-item"><button class="page-link" @onclick="() => PaginationItemClick(nextBlock)"><i class="fas fa-angle-right"></i></button></li>
<li class="page-item"><button class="page-link" @onclick="() => PaginationItemClick(LastPage)"><i class="fas fa-angle-double-right"></i></button></li>
</ul>
}
</div>
</div>
<div class="row">
<div class="col-12 small">
@if (showLoading)
{
<div class="progress" style="height: 10px;">
<div class="progress-bar progress-bar-striped progress-bar-animated" style="width:@percLoading%;"></div>
</div>
}
</div>
</div>
</div>
<div class="col-12 col-lg-3">
<div class="d-flex">
<div class="p-1 flex-fill text-right">
@if (!showLoading)
{
<span>@totalCount records</span>
}
</div>
<div class="p-1 flex-fill text-right small">
@if (totalCount > 0)
{
<div class="input-group input-group-sm">
<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>
</div>
</div>
+189
View File
@@ -0,0 +1,189 @@
using Microsoft.AspNetCore.Components;
using System;
using System.Threading.Tasks;
namespace MP.Prog.Components
{
public partial class DataPager : ComponentBase
{
#region Protected Fields
protected bool _showLoading = false;
#endregion Protected Fields
#region Private Properties
private int endPage
{
get
{
int answ = (int)(currPage / numPages) * numPages + numPages;
answ = answ < LastPage ? answ : LastPage;
return answ;
}
}
private int LastPage
{
get
{
return Math.Max((int)Math.Ceiling(totalCount / (double)PageSize), 1);
}
}
private int nextBlock
{
get
{
int answ = currPage + numPages;
answ = answ < LastPage ? answ : LastPage;
return answ;
}
}
private int numPages { get; set; } = 10;
private int prevBlock
{
get
{
int answ = currPage - numPages;
answ = answ > 0 ? answ : 1;
return answ;
}
}
// calcola un set 1 .. numPages centrato sulla pagina corrente...
private int startPage
{
get
{
int answ = (int)(currPage / numPages) * numPages;
answ = answ > 0 ? answ : 1;
return answ;
}
}
#endregion Private Properties
#region Protected Properties
protected int _numPage { get; set; } = 1;
protected int _numRecord { get; set; } = 10;
protected int percLoading { get; set; } = 0;
#endregion Protected Properties
#region Public Properties
[Parameter]
public int currPage
{
get
{
return _numPage;
}
set
{
bool doReport = !_numPage.Equals(value);
if (doReport)
{
_numPage = value;
reportChangePage();
}
}
}
[Parameter]
public EventCallback<int> numPageChanged { get; set; }
[Parameter]
public EventCallback<int> numRecordChanged { get; set; }
[Parameter]
public int PageSize
{
get
{
return _numRecord;
}
set
{
bool doReport = !_numRecord.Equals(value);
if (doReport)
{
_numRecord = value;
reportChange();
}
}
}
[Parameter]
public bool showLoading
{
get
{
return _showLoading;
}
set
{
if (value)
{
Random random = new Random();
percLoading = random.Next(30, 90);
}
else
{
percLoading = 5;
}
_showLoading = value;
}
}
[Parameter]
public int totalCount { get; set; } = 0;
#endregion Public Properties
#region Private Methods
private void reportChange()
{
numRecordChanged.InvokeAsync(PageSize);
}
private void reportChangePage()
{
numPageChanged.InvokeAsync(currPage);
}
#endregion Private Methods
#region Protected Methods
protected string cssActive(int numPage)
{
string answ = "";
if (numPage == currPage)
{
answ = "active";
}
return answ;
}
protected override async Task OnInitializedAsync()
{
await Task.Run(() => showLoading = false);
}
protected void PaginationItemClick(int page)
{
currPage = page;
}
#endregion Protected Methods
}
}
+154
View File
@@ -0,0 +1,154 @@
@using MP.Prog.Data
@using System.Text
@using DiffMatchPatch
<div class="row">
<div class="col-6 table-success">
<div class="row">
<div class="col-4 text-success">
<h4>Archivio</h4>
</div>
<div class="col-4">
</div>
<div class="col-4 text-right">
<input @bind="@pHeight" class="text-right" width="20" inputmode="numeric" /> <i class="fas fa-arrows-alt-v"></i>
</div>
</div>
</div>
@if (numChanges > 0)
{
<div class="col-6 table-danger">
<div class="row">
<div class="col-4 text-danger">
<h4>Attuale</h4>
</div>
<div class="col-4">
</div>
<div class="col-4 text-right p-2">
<span class="border border-danger table-danger py-1 px-2"><b>@numChanges</b> modifiche</span>
</div>
</div>
</div>
}
</div>
<div class="row" style="height: @(pHeight)em; overflow-y: scroll;">
<div class="col-6 table-success">
<div class="border border-success p-2 bg-light">
<p>@((MarkupString)oldResult)</p>
</div>
</div>
@if (numChanges > 0)
{
<div class="col-6 table-danger">
<div class="border border-danger p-2 bg-light">
<p>@((MarkupString)newResult)</p>
</div>
</div>
}
</div>
@code {
string sepDest = "<br />";
protected int pHeight = 25;
protected string oldResult = "";
protected string newResult = "";
protected string _oldText = "";
protected string _newText = "";
[Parameter]
public EventCallback<int> diffDone { get; set; }
protected int numChanges { get; set; } = 0;
[Parameter]
public string oldText
{
get
{
return _oldText;
}
set
{
_oldText = value;
}
}
protected string oldTextFix
{
get
{
return _oldText.Replace(Environment.NewLine, sepDest).Replace("\n", sepDest).Replace("\r", sepDest);
}
}
protected string newTextFix
{
get
{
return _newText.Replace(Environment.NewLine, sepDest).Replace("\n", sepDest).Replace("\r", sepDest);
}
}
[Parameter]
public string newText
{
get
{
return _newText;
}
set
{
_newText = value;
ReloadData();
}
}
protected void ReloadData()
{
numChanges = 0;
// calcolo diff
diff_match_patch dmp = new diff_match_patch();
List<Diff> diff = dmp.diff_main(oldTextFix, newTextFix);
dmp.diff_cleanupSemantic(diff);
// predispongo la stringa secondo l'elenco dei diff....
StringBuilder sbNew = new StringBuilder();
StringBuilder sbOld = new StringBuilder();
foreach (var item in diff)
{
switch (item.operation)
{
case Operation.DELETE:
sbOld.Append($"<span class=\"border border-success table-success\">{item.text}</span>");
break;
case Operation.INSERT:
sbNew.Append($"<span class=\"border border-danger table-danger\">{item.text}</span>");
numChanges++;
break;
case Operation.EQUAL:
sbNew.Append($"<span class=\"text-dark\">{item.text}</span>");
sbOld.Append($"<span class=\"text-dark\">{item.text}</span>");
break;
default:
break;
}
}
newResult = sbNew.ToString().Trim();
oldResult = sbOld.ToString().Trim();
var pUpd = Task.Run(async () =>
{
await diffDone.InvokeAsync(numChanges);
});
pUpd.Wait();
}
protected override Task OnInitializedAsync()
{
ReloadData();
return base.OnInitializedAsync();
}
}
+31
View File
@@ -0,0 +1,31 @@
<div class="card">
<div class="card-header bg-secondary text-light">
<div class="row">
<div class="col-4">
<h5>Dettaglio modifiche</h5>
</div>
<div class="col-4">
@if (_currItem.DiskStatus != FileData.FileState.Ok)
{
<div class="row">
<div class="col-6">
<button type="button" class="btn btn-success btn-block" value="Cancel" @onclick="RejectChange">Mantieni Archivio <i class="fas fa-file-download"></i></button>
</div>
<div class="col-6">
<button type="button" class="btn btn-danger btn-block" value="Cancel" @onclick="ApproveChange">Accetta Attuale <i class="fas fa-file-upload"></i></button>
</div>
</div>
}
</div>
<div class="col-2">
@numDiff
</div>
<div class="col-2 text-right">
<button type="button" class="btn btn-primary btn-block" value="Cancel" @onclick="cancelUpdate" title="Chiudi">Chiudi <i class="fas fa-window-close"></i></button>
</div>
</div>
</div>
<div class="card-body small py-1">
<MP.Prog.Components.DiffView oldText="@_currItem.FileStringContent" newText="@(CurrFileContent(_currItem.Path))"></MP.Prog.Components.DiffView>
</div>
</div>
+161
View File
@@ -0,0 +1,161 @@
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using MP.FileData.DatabaseModels;
using MP.Prog.Data;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
namespace MP.Prog.Components
{
public partial class FileEditor : ComponentBase
{
#region Protected Fields
protected int numDiff = 0;
#endregion Protected Fields
#region Public Fields
public FileModel _currItem = new FileModel();
#endregion Public Fields
#region Protected Properties
[Inject]
protected FileArchDataService DataService { get; set; }
[Inject]
protected IJSRuntime JSRuntime { get; set; }
#endregion Protected Properties
#region Public Properties
[Parameter]
public FileModel currItem
{
get
{
return _currItem = null;
}
set
{
_currItem = value;
}
}
[Parameter]
public EventCallback<int> DataReset { get; set; }
[Parameter]
public EventCallback<int> DataUpdated { get; set; }
[Parameter]
public List<MacchinaModel> MacList { get; set; }
[Parameter]
public List<TagModel> TagList { get; set; }
#endregion Public Properties
#region Private Methods
private async Task ApproveChange()
{
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Sicuro di voler asccettare la modifica del file selezionato generando una nuova revisione?"))
return;
if (_currItem != null)
{
await DataService.FileApprove(_currItem);
await DataUpdated.InvokeAsync(1);
}
else
{
Console.WriteLine("File null!");
}
}
private async Task cancelUpdate()
{
await DataReset.InvokeAsync(0);
}
private async Task deleteRecord()
{
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Sicuro di voler eliminare il file selezionato??"))
return;
if (_currItem != null)
{
await DataService.FileDelete(_currItem);
await DataUpdated.InvokeAsync(1);
}
else
{
Console.WriteLine("File null!");
}
}
private async Task RejectChange()
{
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Sicuro di voler eliminare la modifica del file selezionato e sovrascrivere la versione in rete?"))
return;
if (_currItem != null)
{
await DataService.FileReject(_currItem);
await DataUpdated.InvokeAsync(1);
}
else
{
Console.WriteLine("File null!");
}
}
private async Task saveUpdate()
{
if (_currItem != null)
{
await DataService.FileUpdate(_currItem);
await DataUpdated.InvokeAsync(1);
}
else
{
Console.WriteLine("File null!");
}
}
#endregion Private Methods
#region Protected Methods
protected void diffDoneHandler(int numChanges)
{
#if false
numDiff = numChanges;
#endif
}
#endregion Protected Methods
#region Public Methods
public string CurrFileContent(string fullPath)
{
string answ = "";
if (File.Exists(fullPath))
{
answ = File.ReadAllText(fullPath);
}
return answ;
}
#endregion Public Methods
}
}
+7
View File
@@ -0,0 +1,7 @@
@*<h1 class="alert alert-info">Working</h1>*@
<div class="row">
<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>
</div>
</div>
+61
View File
@@ -0,0 +1,61 @@
@using Microsoft.AspNetCore.Components.Authorization
@inject AuthenticationStateProvider AuthenticationStateProvider
<AuthorizeView>
<Authorized>
<div class="input-group text-truncate">
<div class="input-group-prepend">
<a title="LogOut" href="Identity/Account/LogOut" class="btn btn-sm btn-danger"><i class="fas fa-sign-out-alt"></i></a>
</div>
<a title="Gestione account @userName" href="Identity/Account/Manage" class="btn btn-sm btn-outline-dark mx-0 px-1">
<div class="d-none d-sm-block">
<i class="fas fa-user-alt"></i> @StringLim(userName, 30)
</div>
<div class="d-block d-sm-none">
<i class="fas fa-user-alt"></i> @StringLim(userName, 15)
</div>
</a>
</div>
</Authorized>
<NotAuthorized>
<div class="input-group">
<div class="input-group-prepend">
<a title="LogIn" href="Identity/Account/LogIn" class="btn btn-sm btn-success"><i class="fas fa-sign-in-alt"></i></a>
</div>
<div class="form-control form-control-sm">
<i class="fas fa-user-alt"></i>&nbsp;@userName
</div>
</div>
</NotAuthorized>
</AuthorizeView>
@code{
private string userName = "";
protected override async Task OnInitializedAsync()
{
await forceReload();
}
private async Task forceReload()
{
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
var user = authState.User;
if (user.Identity.IsAuthenticated)
{
userName = $"{user.Identity.Name}";
}
else
{
userName = "Non Autenticato";
}
}
protected string StringLim(string original, int maxLen)
{
return original.Length <= maxLen ? original : $"{original.Substring(0, maxLen - 3)}...";
}
}
+43
View File
@@ -0,0 +1,43 @@
@using MP.Prog.Components
@using MP.Prog.Data
@using Majorsoft.Blazor.Components.Debounce
@inject MessageService MessageService
<div class="input-group input-group-sm">
<DebounceInput id="sVal" class="form-control" placeholder="@("Ricerca (min " + _minChar + " char)")" autocomplete="off" @ref="debInput" @bind-Value="@_searchVal" @bind-Value:event="OnInput" DebounceTime="@_debMsec" MinLength="@_minChar" OnValueChanged="e => { searchVal = e; }" ForceNotifyByEnter="true" ForceNotifyOnBlur="true" />
<div class="input-group-append">
<button @onclick="reset" class="btn btn-success input-group-text">reset</button>
</div>
</div>
@code {
private string _searchVal = "";
private int _debMsec = 200;
private int _minChar = 2;
private DebounceInput debInput;
[Parameter]
public string searchVal
{
get
{
return MessageService.SearchVal;
}
set
{
if (!MessageService.SearchVal.Equals(value))
{
MessageService.SearchVal = value;
}
}
}
private void reset()
{
_searchVal = "";
searchVal = "";
}
}
+36
View File
@@ -0,0 +1,36 @@
<div class="modal fade show" id="myModal" style="display:block; background-color: rgba(10,10,10,.8);"
aria-modal="true" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">@Title</h4>
<button type="button" class="close" @onclick="@ModalCancel">&times;</button>
</div>
<div class="modal-body">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text">
<span class="fas fa-search" aria-hidden="true"></span>
</span>
</div>
<input type="text" class="form-control form-control-sm" placeholder="Ricerca Tag" @bind-value="@SearchTag" />
<select @bind="@SelTag" class="form-control form-control-sm">
@if (TagList != null)
{
foreach (var item in TagList)
{
<option value="@item.ValueField">@item.LabelField</option>
}
}
</select>
<div class="input-group-append">
<button id="searchReset" class="btn btn-sm btn-secondary" @onclick="() => ResetSearchTag()" title="Reset ricerca articolo"><i class="fas fa-ban"></i></button>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" @onclick=@ModalOk>OK</button>
</div>
</div>
</div>
</div>
+142
View File
@@ -0,0 +1,142 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
using MP.FileData.DatabaseModels;
using MP.Prog;
using MP.Prog.Data;
namespace MP.Prog.Components
{
public partial class TagSearch
{
#region Protected Fields
protected string _SearchTag;
protected string defTag = "###";
protected string LastSelTag = "";
#endregion Protected Fields
#region Protected Properties
[Inject]
protected MessageService AppMService { get; set; }
[Inject]
protected FileArchDataService DataService { get; set; }
protected string SearchTag
{
get
{
return _SearchTag;
}
set
{
_SearchTag = value;
// se son > 3 char... debounce...
if (string.IsNullOrEmpty(value))
{
_SearchTag = defTag;
}
if (value.Length >= defTag.Length)
{
var pUpd = Task.Run(async () =>
{
TagList = await DataService.TagGetSearch(_SearchTag, 50);
});
pUpd.Wait();
}
}
}
protected List<AutocompleteModel> TagList { get; set; } = new List<AutocompleteModel>();
#endregion Protected Properties
#region Public Properties
[Parameter]
public EventCallback<bool> OnClose { get; set; }
[Parameter]
public EventCallback<string> searchUpdated { get; set; }
[Parameter]
public string SelTag
{
get
{
string answ = "";
if (AppMService.File_Filter != null)
{
answ = AppMService.File_Filter.Tag;
}
return answ;
}
set
{
if (!AppMService.File_Filter.Tag.Equals(value))
{
AppMService.File_Filter.Tag = value;
}
reportChange();
}
}
[Parameter]
public string Text { get; set; }
[Parameter]
public string Title { get; set; }
#endregion Public Properties
#region Private Methods
private Task ModalCancel()
{
// resetto ricerca
SelTag = LastSelTag;
return OnClose.InvokeAsync(false);
}
private Task ModalOk()
{
return OnClose.InvokeAsync(true);
}
private void reportChange()
{
searchUpdated.InvokeAsync(SelTag);
}
#endregion Private Methods
#region Protected Methods
protected override async Task OnInitializedAsync()
{
LastSelTag = SelTag;
await ReloadAllData();
_SearchTag = defTag;
}
protected async Task ReloadAllData()
{
SelTag = defTag;
TagList = await DataService.TagGetSearch(SearchTag, 20);
}
protected async Task ResetSearchTag()
{
SearchTag = defTag;
await Task.Delay(1);
}
#endregion Protected Methods
}
}
+1
View File
@@ -0,0 +1 @@

+29
View File
@@ -0,0 +1,29 @@
{
"ExcludedTags": [
"M4",
"M5",
"M4+A",
"M4+B",
"M5+A",
"M5+B"
],
"ExcludedFileExt": [
".xls",
".xls#",
".xlsx"
],
"FileNameExtReplace": {
".P-2": ""
},
"MaxChar2Search": 100,
"Mode": 0,
"Name": "Tag da Commento Filename",
"OutExcludeFileName": true,
"OutReplace": {
"(": " ",
")": " "
},
"RegExPattern": "\\b{{fileName}}.{0,2}\\([\\w\\d\\s./\\-=]+\\)",
"RegExRepFileName": true,
"ReplaceCR": true
}
+23
View File
@@ -0,0 +1,23 @@
{
"ExcludedTags": [],
"ExcludedFileExt": [
".xls",
".xls#",
".xlsx"
],
"FileNameExtReplace": {
".P-2": ""
},
"MaxChar2Search": 1,
"Mode": 1,
"Name": "Tag da Directory + Filename",
"OutExcludeFileName": false,
"OutReplace": {
".WPD": "",
".MPF": "",
".SPF": ""
},
"RegExPattern": "",
"RegExRepFileName": true,
"ReplaceCR": false
}
+35
View File
@@ -0,0 +1,35 @@
{
"ExcludedTags": [
"M4",
"M5",
"M4+A",
"M4+B",
"M5+A",
"M5+B",
"M6+A",
"M6+B",
"+A"
],
"ExcludedFileExt": [
".xls",
".xls#",
".xlsx"
],
"FileNameExtReplace": {
".P-2": "",
".tim": ""
},
"MaxChar2Search": 100,
"Mode": 0,
"Name": "Tag da Commento Filename Tornoss TISIS",
"OutExcludeFileName": true,
"OutReplace": {
"(": " ",
")": " ",
"<": " ",
">": " "
},
"RegExPattern": "\\b{{fileName}}.{0,2}\\([\\<\\w\\d\\s./\\-=\\+\\>]+\\)",
"RegExRepFileName": true,
"ReplaceCR": true
}
+17
View File
@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace MP.Prog.Data
{
public class AutocompleteModel
{
#region Public Properties
public string LabelField { get; set; }
public string ValueField { get; set; }
#endregion Public Properties
}
}
+341
View File
@@ -0,0 +1,341 @@
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using MP.FileData;
using Newtonsoft.Json;
using NLog;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using MP.FileData.Controllers;
using MP.FileData.DTO;
namespace MP.Prog.Data
{
public class FileArchDataService : IDisposable
{
#region Private Fields
private static IConfiguration _configuration;
private static ILogger<FileArchDataService> _logger;
private static List<FileData.DatabaseModels.MacchinaModel> ElencoMacchine = new List<FileData.DatabaseModels.MacchinaModel>();
private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
private readonly IDistributedCache distributedCache;
private readonly IMemoryCache memoryCache;
/// <summary>
/// Durata assoluta massima della cache
/// </summary>
private int chAbsExp = 15;
/// <summary>
/// Durata della cache in modalità inattiva (non acceduta) prima di venire rimossa
/// NON estende oltre il tempo massimo di validità della cache (chAbsExp)
/// </summary>
private int chSliExp = 5;
#endregion Private Fields
#region Protected Fields
protected static string connStringBBM = "";
protected static string connStringFatt = "";
#endregion Protected Fields
#region Public Fields
public static FileData.Controllers.FileController dbController;
#endregion Public Fields
#region Public Constructors
public FileArchDataService(IConfiguration configuration, ILogger<FileArchDataService> logger, IMemoryCache memoryCache, IDistributedCache distributedCache)
{
_logger = logger;
_configuration = configuration;
// conf cache
this.memoryCache = memoryCache;
this.distributedCache = distributedCache;
// conf DB
string connStr = _configuration.GetConnectionString("Mp.Prog");
if (string.IsNullOrEmpty(connStr))
{
_logger.LogError("ConnString empty!");
}
else
{
dbController = new FileData.Controllers.FileController(configuration);
_logger.LogInformation("DbController OK");
}
}
#endregion Public Constructors
#region Private Properties
private DistributedCacheEntryOptions cacheOpt
{
get
{
return new DistributedCacheEntryOptions().SetAbsoluteExpiration(DateTime.Now.AddMinutes(chAbsExp)).SetSlidingExpiration(TimeSpan.FromMinutes(chSliExp));
}
}
private DistributedCacheEntryOptions cacheOptLong
{
get
{
return new DistributedCacheEntryOptions().SetAbsoluteExpiration(DateTime.Now.AddMinutes(chAbsExp * 10)).SetSlidingExpiration(TimeSpan.FromMinutes(chSliExp));
}
}
#endregion Private Properties
#region Internal Methods
internal Task FileApprove(FileData.DatabaseModels.FileModel currItem)
{
return Task.FromResult(dbController.FileModApprove(currItem));
}
internal Task FileDelete(FileData.DatabaseModels.FileModel currItem)
{
return Task.FromResult(dbController.FileDelete(currItem));
}
internal Task FileReject(FileData.DatabaseModels.FileModel currItem)
{
return Task.FromResult(dbController.FileModReject(currItem));
}
internal Task FileUpdate(FileData.DatabaseModels.FileModel updItem)
{
return Task.FromResult(dbController.FileUpdate(updItem));
}
internal void ResetController()
{
dbController.ResetController();
}
#endregion Internal Methods
#region Public Methods
public void Dispose()
{
// Clear database controller
dbController.Dispose();
}
public async Task<int> FileCountFilt(SelectData CurrFilter)
{
int numCount = 0;
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
numCount = dbController.FileCountFilt(CurrFilter.IdxMacchina, CurrFilter.OnlyActive, CurrFilter.OnlyMod, CurrFilter.OnlyNoTag, CurrFilter.FileName, CurrFilter.Tag, CurrFilter.SearchVal);
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Trace($"Effettuata lettura da DB per FileCountFilt: {ts.TotalMilliseconds} ms");
return await Task.FromResult(numCount);
}
public Task<FileData.DatabaseModels.FileModel> FileGetByKey(int FileId)
{
return Task.FromResult(dbController.FileGetByKey(FileId));
}
public async Task<List<FileData.DatabaseModels.FileModel>> FileGetFilt(SelectData CurrFilter)
{
List<FileData.DatabaseModels.FileModel> dbResult = new List<FileData.DatabaseModels.FileModel>();
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
dbResult = dbController.FileGetFilt(CurrFilter.IdxMacchina, CurrFilter.OnlyActive, CurrFilter.OnlyMod, CurrFilter.OnlyNoTag, CurrFilter.FileName, CurrFilter.Tag, CurrFilter.SearchVal, CurrFilter.NumSkip, CurrFilter.PageSize).ToList();
//dbResult = dbController.FileGetFilt(CurrFilter.IdxMacchina, CurrFilter.OnlyActive, CurrFilter.OnlyMod, CurrFilter.FirstRecord, CurrFilter.PageSize * 10, CurrFilter.SearchVal).ToList();
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Trace($"Effettuata lettura da DB per FileGetFilt: {ts.TotalMilliseconds} ms");
return await Task.FromResult(dbResult);
}
public async Task<List<ArchiveStatusDTO>> GetArchiveStatus()
{
List<ArchiveStatusDTO> dbResult = new List<ArchiveStatusDTO>();
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
dbResult = dbController.GetArchiveStatus();
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Trace($"Effettuata lettura da DB per GetArchiveStatus: {ts.TotalMilliseconds} ms");
return await Task.FromResult(dbResult);
}
public Task<FileData.DatabaseModels.MacchinaModel> MacchinaGetByKey(string idxMacchina)
{
return Task.FromResult(dbController.MacchinaGetByKey(idxMacchina));
}
public Task<List<FileData.DatabaseModels.MacchinaModel>> MacchineGetAll()
{
return Task.FromResult(dbController.MacchineGetAll().ToList());
}
public async Task<List<AutocompleteModel>> MachineList()
{
List<AutocompleteModel> answ = new List<AutocompleteModel>();
answ.Add(new AutocompleteModel { LabelField = "--- TUTTE ---", ValueField = "*" });
answ.AddRange(dbController.MacchineGetAll().Select(x => new AutocompleteModel { LabelField = $"{x.IdxMacchina} | {x.Nome} {x.Descrizione} ", ValueField = x.IdxMacchina }).ToList());
return await Task.FromResult(answ);
}
public void rollBackEdit(object item)
{
dbController.RollBackEntity(item);
}
public async Task<List<FileData.DatabaseModels.TagModel>> TagGetFilt(string SearchVal)
{
return await Task.FromResult(dbController.TagGetFilt(SearchVal, 200).ToList());
}
public Task<List<AutocompleteModel>> TagGetSearch(string searchVal, int numRecord)
{
List<AutocompleteModel> answ = new List<AutocompleteModel>();
answ.Add(new AutocompleteModel { LabelField = "--- TUTTE ---", ValueField = "*" });
if (numRecord > -1)
{
answ.AddRange(dbController.TagGetFilt(searchVal, numRecord).Select(x => new AutocompleteModel { LabelField = $"{x.TagId}", ValueField = x.TagId }).ToList());
}
return Task.FromResult(answ);
}
#if false
protected string getCacheKey(string TableName, SelectData CurrFilter)
{
string answ = $"{TableName}:M_{CurrFilter.IdxMacchina}:A_{CurrFilter.CodArticolo}:K_{CurrFilter.KeyRichiesta}:O_{CurrFilter.IdxOdl}:D_{CurrFilter.DateStart:yyyyMMddHHmm}_{CurrFilter.DateEnd:yyyyMMddHHmm}";
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;
}
#endif
/// <summary>
/// Aggiorna intero archivio scansionando dati x tutte le macchine che hanno un path valido
/// </summary>
/// <param name="numDayPre">Numero giorni x ricerca all'indietro da data corrente / 0 = nessun limite</param>
/// <returns></returns>
public async Task<int> updateAllArchive(int numDayPre, bool forceTag)
{
int checkDone = 0;
var listaMacchine = await MacchineGetAll();
foreach (var item in listaMacchine.Where(x => !string.IsNullOrEmpty(x.BasePath)).ToList())
{
checkDone += await updateMachineArchive(item.IdxMacchina, numDayPre, forceTag, false);
}
return await Task.FromResult(checkDone);
}
/// <summary>
/// Aggiorna archivio di una amcchina scansionando path relativo
/// </summary>
/// <param name="idxMacchina">Codice macchina</param>
/// <param name="numDayPre">Numero giorni x ricerca all'indietro da data corrente / 0 = nessun limite</param>
/// <param name="forceTag">Forza la riverifica dei tags (x update da setup)</param>
/// <param name="fullLog">Scrittura log verboso macchina</param>
/// <returns></returns>
public async Task<int> updateMachineArchive(string idxMacchina, int numDayPre, bool forceTag, bool fullLog)
{
int checkDone = 0;
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
string ruleName = "Rule00.json";
try
{
var macchina = MacchinaGetByKey(idxMacchina).Result;
if (macchina != null && !string.IsNullOrEmpty(macchina.BasePath))
{
if (!string.IsNullOrEmpty(macchina.RuleName))
{
ruleName = macchina.RuleName;
// gestione confRule...
SearchRules currRule = new SearchRules();
try
{
string rawData = File.ReadAllText(FileController.rulePath(ruleName));
currRule = JsonConvert.DeserializeObject<SearchRules>(rawData);
//Log.Info($"Conf rule acquisito da file {ruleName}:{Environment.NewLine}{rawData}");
}
catch (Exception exc)
{
Log.Error($"Eccezione in deserializzazione conf rule{Environment.NewLine}{exc}");
}
// se NON deserializzato inizializzo hard-coded
if (currRule.Name == "ND")
{
// fare: lettura conf rule x recupero tag x singola macchina
//$"\\b{fileName}" + @".{0,2}\([\w\d\s.]+\)";
Dictionary<string, string> confReplace = new Dictionary<string, string>();
confReplace.Add("(", " ");
confReplace.Add(")", " ");
Dictionary<string, string> fileExtReplace = new Dictionary<string, string>();
fileExtReplace.Add(".P-2", "");
// hard coded + salvataggio conf x creare json
currRule = new SearchRules()
{
Name = "Commento Filename",
Mode = SearchMode.StringOnFile,
MaxChar2Search = 100,
ReplaceCR = true,
RegExPattern = "\\b{{fileName}}" + @".{0,2}\([\w\d\s./]+\)",
RegExRepFileName = true,
FileNameExtReplace = fileExtReplace,
ExcludedTags = new List<string>() { "M4", "M5", "M4+A", "M4+B", "M5+A", "M5+B" },
OutReplace = confReplace,
OutExcludeFileName = true
};
if (fullLog)
{
// serializzo
string rawRule = JsonConvert.SerializeObject(currRule, Formatting.Indented);
Log.Trace($"Conf rule generato:{Environment.NewLine}{rawRule}");
}
}
checkDone = dbController.CheckFileArchived(macchina.IdxMacchina, macchina.BasePath, numDayPre, "*.*", forceTag, currRule);
}
}
}
catch (Exception exc)
{
Log.Error($"Eccezione in updateMachineArchive{Environment.NewLine}{exc}{Environment.NewLine}{exc.InnerException}");
}
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Info($"Effettuato update archivio file MACCHINA | last {numDayPre} days | {checkDone} checked | {ts.TotalMilliseconds} ms");
return await Task.FromResult(checkDone);
}
#endregion Public Methods
}
}
+155
View File
@@ -0,0 +1,155 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Timers;
namespace MP.Prog.Data
{
public class MessageService
{
#region Private Fields
private SelectData _fileFilter = SelectData.Init(5, 15);
private string _pageIcon;
private string _pageName;
private string _searchVal = "";
private bool showSearch;
#endregion Private Fields
#region Public Events
public event Action EA_FilterUpdated;
public event Action EA_HideSearch;
public event Action EA_PageUpdated;
public event Action EA_SearchUpdated;
public event Action EA_ShowSearch;
#endregion Public Events
#region Public Properties
public SelectData File_Filter
{
get => _fileFilter;
set
{
if (_fileFilter != value)
{
_fileFilter = value;
ReportFilter();
}
}
}
public string PageIcon
{
get => _pageIcon;
set
{
if (_pageIcon != value)
{
_pageIcon = value;
ReportPageUpd();
}
}
}
public string PageName
{
get => _pageName;
set
{
if (_pageName != value)
{
_pageName = value;
ReportPageUpd();
}
}
}
public string SearchVal
{
get => _searchVal;
set
{
if (_searchVal != value)
{
_searchVal = value;
ReportSearch();
}
}
}
public bool ShowSearch
{
get => showSearch;
set
{
if (showSearch != value)
{
showSearch = value;
if (showSearch)
{
ReportShowSearch();
}
else
{
ReportHideSearch();
}
}
}
}
#endregion Public Properties
#region Private Methods
private void ReportFilter()
{
if (EA_FilterUpdated != null)
{
EA_FilterUpdated?.Invoke();
}
}
private void ReportHideSearch()
{
if (EA_HideSearch != null)
{
EA_HideSearch?.Invoke();
}
}
private void ReportPageUpd()
{
if (EA_PageUpdated != null)
{
EA_PageUpdated?.Invoke();
}
}
private void ReportSearch()
{
if (EA_SearchUpdated != null)
{
EA_SearchUpdated?.Invoke();
}
}
private void ReportShowSearch()
{
if (EA_ShowSearch != null)
{
EA_ShowSearch?.Invoke();
}
}
#endregion Private Methods
}
}
+113
View File
@@ -0,0 +1,113 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace MP.Prog.Data
{
public class SelectData
{
#region Public Properties
public DateTime DateEnd { get; set; } = DateTime.Now.AddMinutes(1);
public DateTime DateStart { get; set; } = DateTime.Now.AddDays(-7);
public string FileName { get; set; } = "";
/// <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; } = "";
/// <summary>
/// Recorda da saltare x arrivare alla pagina corrente
/// </summary>
public int NumSkip
{
get
{
return PageSize * (PageNum - 1);
}
}
public bool OnlyActive { get; set; } = true;
public bool OnlyMod { get; set; } = false;
public bool OnlyNoTag { get; set; } = false;
public int PageNum { get; set; } = 1;
public int PageSize { get; set; } = 10;
public string SearchVal { get; set; } = "";
public string Tag { get; set; } = "";
#endregion Public Properties
#region Public Methods
/// <summary>
/// Inizializzazione con periodo e arrotondamento
/// </summary>
/// <param name="minRound"></param>
/// <param name="numDayPrev"></param>
/// <returns></returns>
public static SelectData Init(int minRound, int numDayPrev)
{
TimeSpan DayElapsed = DateTime.Now.Subtract(DateTime.Today);
int minDay = (int)((DayElapsed.TotalMinutes / minRound) + 1) * minRound;
DateTime endRounded = DateTime.Today.AddMinutes(minDay);
SelectData answ = new SelectData()
{
DateEnd = endRounded,
DateStart = endRounded.AddDays(-numDayPrev),
SearchVal = ""
};
return answ;
}
public override bool Equals(object obj)
{
if (!(obj is SelectData item))
return false;
if (PageSize != item.PageSize)
return false;
if (PageNum != item.PageNum)
return false;
if (OnlyActive != item.OnlyActive)
return false;
if (OnlyMod != item.OnlyMod)
return false;
if (OnlyNoTag != item.OnlyNoTag)
return false;
if (SearchVal != item.SearchVal)
return false;
if (FileName != item.FileName)
return false;
if (IdxMacchina != item.IdxMacchina)
return false;
if (Tag != item.Tag)
return false;
if (DateEnd != item.DateEnd)
return false;
if (DateStart != item.DateStart)
return false;
return true;
}
public override int GetHashCode()
{
return base.GetHashCode();
}
#endregion Public Methods
}
}
@@ -0,0 +1,39 @@
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.WebUtilities;
namespace MP.Prog.Extensions
{
public static class NavigationManagerExtension
{
#region Public Methods
/// <summary>
/// Estensione metodo NavigationManager
///
/// https://code-maze.com/query-strings-blazor-webassembly/
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="navManager"></param>
/// <param name="key"></param>
/// <returns></returns>
public static T ExtractQueryStringByKey<T>(this NavigationManager navManager, string key)
{
var uri = navManager.ToAbsoluteUri(navManager.Uri);
QueryHelpers.ParseQuery(uri.Query)
.TryGetValue(key, out var queryValue);
if (typeof(T).Equals(typeof(int)))
{
int.TryParse(queryValue, out int result);
return (T)(object)result;
}
if (typeof(T).Equals(typeof(string)))
return (T)(object)queryValue.ToString();
return default;
}
#endregion Public Methods
}
}
+33
View File
@@ -0,0 +1,33 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<RootNamespace>MP.Prog</RootNamespace>
<Version>1.1.2109.1612</Version>
</PropertyGroup>
<ItemGroup>
<Content Remove="Components\CodArtSelector.razor" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="DiffMatchPatch" Version="1.0.3" />
<PackageReference Include="Majorsoft.Blazor.Components.Debounce" Version="1.5.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.9">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="5.0.1" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="5.0.2" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="NLog.Web.AspNetCore" Version="4.14.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MP.FileData\MP.FileData.csproj" />
</ItemGroup>
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="powershell.exe -ExecutionPolicy Unrestricted -NoProfile -NonInteractive -File $(ProjectDir)\post-build.ps1 -ProjectDir $(ProjectDir) -ProjectPath $(ProjectPath)" />
</Target>
</Project>
+46
View File
@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
autoReload="true"
throwExceptions="false"
internalLogLevel="Off" internalLogFile="c:\temp\nlog-internal.log">
<!-- optional, add some variables
https://github.com/nlog/NLog/wiki/Configuration-file#variables
-->
<variable name="myvar" value="myvalue" />
<!--
See https://github.com/nlog/nlog/wiki/Configuration-file
for information on customizing logging rules and outputs.
-->
<targets>
<!--
add your targets here
See https://github.com/nlog/NLog/wiki/Targets for possible targets.
See https://github.com/nlog/NLog/wiki/Layout-Renderers for the possible layout renderers.
-->
<!--
Write events to a file with the date in the filename.
<target xsi:type="File" name="f" fileName="${basedir}/logs/${shortdate}.log"
layout="${longdate} ${uppercase:${level}} ${message}" />
-->
<target xsi:type="File" name="fileTarget" fileName="${basedir}/logs/${shortdate}.log" layout="${longdate} | ${uppercase:${level}} | ${logger:shortName=false} | ${message}" />
<target xsi:type="ColoredConsole" name="consoleTarget" layout="${longdate} | ${uppercase:${level}} | ${logger:shortName=true}| ${message}" />
</targets>
<rules>
<!-- add your logging rules here -->
<!--
Write all events with minimal level of Debug (So Debug, Info, Warn, Error and Fatal, but not Trace) to "f"
<logger name="*" minlevel="Debug" writeTo="f" />
-->
<logger name="*" minlevel="Trace" writeTo="consoleTarget" />
<!--<logger name="Microsoft.*" maxlevel="Info" final="true" />-->
<logger name="*" minlevel="Info" writeTo="fileTarget" />
</rules>
</nlog>
+208
View File
@@ -0,0 +1,208 @@
@page "/Archive"
@using MP.Prog.Components
<div class="card">
<div class="card-header table-primary">
<div class="row">
<div class="col-12 col-lg-4">
<div class="d-flex">
<div class="px-2">
<h3>Elenco Programmi</h3>
</div>
<div class="px-2">
<div class="form-group mb-0">
<button id="btnForceCheck" class="btn btn-warning btn-sm" @onclick="() => ForceCheck(30)" title="Analisi Modifiche ultimi 30gg">
<i class="fas fa-sync-alt"></i> Update (30gg) <i class="far fa-folder-open"></i>
</button>
</div>
</div>
</div>
</div>
<div class="col-12 col-lg-8 text-right">
<div class="d-flex flex-row-reverse">
<div class="px-2">
<div class="form-group mb-0">
<button id="btnReset" class="btn btn-info btn-sm" @onclick="() => ResetFilter()" title="Reset Filter"><span class="oi oi-loop-circular"></span></button>
</div>
</div>
<div class="px-2">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text">
<span class="fas fa-industry" aria-hidden="true"></span>
</span>
</div>
<select @bind="@SelIdxMacc" class="form-control form-control-sm">
@if (MacList != null)
{
foreach (var item in MacList)
{
<option value="@item.IdxMacchina">@item.Descrizione (@item.RuleName)</option>
}
}
</select>
</div>
</div>
<div class="px-2">
<div class="input-group input-group-sm">
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" id="togModificati" title="Solo Aperti / Mostra tutti" @bind-value="@OnlyMod" checked="@OnlyMod" />
<label class="custom-control-label" for="togModificati"><sub>Mod</sub></label>
</div>
</div>
</div>
<div class="px-2">
<div class="input-group input-group-sm">
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" id="togAttivi" title="Solo Attivi / Mostra tutti" @bind-value="@OnlyActive" checked="@OnlyActive" />
<label class="custom-control-label" for="togAttivi"><sub>Attivi</sub></label>
</div>
</div>
</div>
<div class="px-2">
<div class="input-group input-group-sm">
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" id="togNoTag" title="Solo senza Tag / Mostra tutti" @bind-value="@OnlyNoTag" checked="@OnlyNoTag" />
<label class="custom-control-label" for="togNoTag"><sub>No Tag</sub></label>
</div>
</div>
</div>
<div class="px-2">
@if (!string.IsNullOrEmpty(SelFileName))
{
<span class="badge badge-secondary">@SelFileName</span>
}
</div>
<div class="px-2">
<div class="input-group input-group-sm">
<div class="input-group-prepend">
<button type="button" class="btn btn-sm btn-primary" @onclick="() => OpenDialog()" title="Aggiunta Tag">
<i class="fas fa-search"></i>
</button>
<span class="input-group-text">Tags</span>
</div>
<div class="form-control form-control-sm">
@if (!string.IsNullOrEmpty(SelTag))
{
<span class="badge badge-info">@SelTag</span>
}
else
{
<span> &nbsp; ... &nbsp; </span>
}
</div>
<div class="input-group-append">
<button type="button" class="btn btn-sm btn-secondary" @onclick="() => ResetTag()" title="Reset Tag">
<i class="fas fa-sync"></i>
</button>
</div>
</div>
@if (DeleteDialogOpen)
{
<MP.Prog.Components.TagSearch Title="Ricerca Tag" OnClose="@OnDialogClose"></MP.Prog.Components.TagSearch>
}
</div>
</div>
</div>
</div>
</div>
<div class="card-body p-1">
@if (currRecord != null)
{
<FileEditor currItem="@currRecord" DataReset="ResetData" DataUpdated="UpdateData" TagList="@TagList" MacList="@MacList"></FileEditor>
}
@if (ListRecords == null)
{
<LoadingData></LoadingData>
}
else if (totalCount == 0)
{
<div class="alert alert-warning text-center display-4">Nessun record trovato</div>
}
else
{
<div class="row">
<div class="col-12">
<table class="table table-sm table-striped table-responsive-lg">
<thead>
<tr>
<th></th>
<th>File</th>
<th>Rev</th>
<th>Size</th>
<th class="text-center">State</th>
<th>Macchina</th>
<th>Tags</th>
<th class="text-right">Modificato</th>
@*<th>Controllo</th>*@
<th></th>
</tr>
</thead>
<tbody>
@foreach (var record in ListRecords)
{
<tr class="@checkSelect(record.FileId)">
<td class="text-nowrap">
@if (currRecord == null && record.Active)
{
<button class="btn btn-sm btn-info" @onclick="() => Edit(record)" title="Edit record #@record.FileId">
<i class="oi oi-pencil"></i>
</button>
}
else
{
<button class="btn btn-sm btn-secondary disabled">
<i class="oi oi-pencil"></i>
</button>
}
</td>
<td>
<div class="@(cssActive(record.Active))">
<div>@record.Name</div>
<button class="btn btn-sm btn-outline-secondary px-1 py-0" @onclick="() => FilterPath(record.Path)" title="Filtra per FilePath">
<div class="small">@record.Path</div>
</button>
</div>
</td>
<td>
<div>@record.Rev</div>
</td>
<td>
<div>@((((double)record.Size)/1024).ToString("N2")) k</div>
</td>
<td class="text-center">
<span title="@record.DiskStatus | Ultimo controllo: @record.LastCheck.ToString(" yyyy.MM.dd HH:mm:ss")">
<span class="@(cssStatusByCod(record.DiskStatus))">
@record.DiskStatus
</span>
</span>
</td>
<td>
<div>@record.Macchina.Nome</div>
<div class="small">@record.Macchina.Descrizione</div>
</td>
<td>
@foreach (var item in record.Tags)
{
<button class="btn btn-sm btn-outline-info px-1 py-0 mr-1" @onclick="() => FilterTag(item.TagId)" title="Filtra Tag">
<div class="small">@item.TagId</div>
</button>
}
</td>
<td class="text-right">
<div>@record.LastMod.ToString("yyyy.MM.dd")</div>
<div class="small">@record.LastMod.ToString("ddd HH:mm.ss")</div>
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
}
</div>
<div class="card-footer p-1">
<DataPager PageSize="numRecord" currPage="currPage" numRecordChanged="PagerReloadNum" numPageChanged="PagerReloadPage" totalCount="totalCount" showLoading="isLoading" />
</div>
</div>
+523
View File
@@ -0,0 +1,523 @@
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using MP.FileData.DatabaseModels;
using MP.Prog.Data;
using NLog;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace MP.Prog.Pages
{
public partial class Archive : ComponentBase, IDisposable
{
#region Private Fields
private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
private FileModel currRecord = null;
private List<FileModel> ListRecords;
private List<MacchinaModel> MacList;
private List<TagModel> TagList;
#endregion Private Fields
#region Protected Fields
protected string _SearchTag;
protected string defTag = "";
protected int totalCount = 0;
#endregion Protected Fields
#region Private Properties
private int currPage
{
get
{
return AppMService.File_Filter.PageNum;
}
set
{
AppMService.File_Filter.PageNum = value;
}
}
private bool isLoading { get; set; } = false;
private int numRecord
{
get
{
return AppMService.File_Filter.PageSize;
}
set
{
AppMService.File_Filter.PageSize = value;
}
}
private bool OnlyActive
{
get
{
bool answ = false;
if (AppMService.File_Filter != null)
{
answ = AppMService.File_Filter.OnlyActive;
}
return answ;
}
set
{
if (!AppMService.File_Filter.OnlyActive.Equals(value))
{
AppMService.File_Filter.OnlyActive = value;
var pUpd = Task.Run(async () =>
{
await AsyncReload();
});
pUpd.Wait();
}
}
}
private bool OnlyMod
{
get
{
bool answ = false;
if (AppMService.File_Filter != null)
{
answ = AppMService.File_Filter.OnlyMod;
}
return answ;
}
set
{
if (!AppMService.File_Filter.OnlyMod.Equals(value))
{
AppMService.File_Filter.OnlyMod = value;
var pUpd = Task.Run(async () =>
{
await AsyncReload();
});
pUpd.Wait();
}
}
}
private bool OnlyNoTag
{
get
{
bool answ = false;
if (AppMService.File_Filter != null)
{
answ = AppMService.File_Filter.OnlyNoTag;
}
return answ;
}
set
{
if (!AppMService.File_Filter.OnlyNoTag.Equals(value))
{
AppMService.File_Filter.OnlyNoTag = value;
var pUpd = Task.Run(async () =>
{
await AsyncReload();
});
pUpd.Wait();
}
}
}
private string SearchVal
{
get
{
string answ = "";
if (AppMService.File_Filter != null)
{
answ = AppMService.File_Filter.SearchVal;
}
return answ;
}
set
{
if (!AppMService.File_Filter.SearchVal.Equals(value))
{
AppMService.File_Filter.SearchVal = value;
var pUpd = Task.Run(async () =>
{
await AsyncReload();
});
pUpd.Wait();
}
}
}
private string SelFileName
{
get
{
string answ = "";
if (AppMService.File_Filter != null)
{
answ = AppMService.File_Filter.FileName;
}
return answ;
}
set
{
if (!AppMService.File_Filter.FileName.Equals(value))
{
AppMService.File_Filter.FileName = value;
var pUpd = Task.Run(async () =>
{
await AsyncReload();
});
pUpd.Wait();
}
}
}
private string SelIdxMacc
{
get
{
string answ = "";
if (AppMService.File_Filter != null)
{
answ = AppMService.File_Filter.IdxMacchina;
}
return answ;
}
set
{
if (!AppMService.File_Filter.IdxMacchina.Equals(value))
{
AppMService.File_Filter.IdxMacchina = value;
var pUpd = Task.Run(async () =>
{
await AsyncReload();
});
pUpd.Wait();
}
}
}
private string SelTag
{
get
{
string answ = "";
if (AppMService.File_Filter != null)
{
answ = AppMService.File_Filter.Tag;
}
return answ;
}
set
{
if (!AppMService.File_Filter.Tag.Equals(value))
{
AppMService.File_Filter.Tag = value;
var pUpd = Task.Run(async () =>
{
await AsyncReload();
});
pUpd.Wait();
}
}
}
#endregion Private Properties
#region Protected Properties
[Inject]
protected MessageService AppMService { get; set; }
[Inject]
protected FileArchDataService DataService { get; set; }
[Inject]
protected IJSRuntime JSRuntime { get; set; }
[Inject]
protected NavigationManager NavManager { get; set; }
protected string SearchTag
{
get
{
return _SearchTag;
}
set
{
_SearchTag = value;
// se son > 3 char... debounce...
if (string.IsNullOrEmpty(value))
{
_SearchTag = defTag;
}
if (value.Length >= defTag.Length)
{
var pUpd = Task.Run(async () =>
{
TagList = await DataService.TagGetFilt(SearchTag);
});
pUpd.Wait();
}
isLoading = false;
}
}
#endregion Protected Properties
#region Public Properties
public bool DeleteDialogOpen { get; set; }
#endregion Public Properties
#region Private Methods
private string cssActive(bool active)
{
string answ = active ? "text-dark" : "text-secondary textStriked";
return answ;
}
private string cssStatusByCod(FileData.FileState currStatus)
{
string answ = "badge";
switch (currStatus)
{
case FileData.FileState.Changed:
answ += " badge-warning";
break;
case FileData.FileState.Deleted:
answ += " badge-danger";
break;
case FileData.FileState.Ok:
answ += " badge-success";
break;
case FileData.FileState.ND:
default:
answ += " badge-light";
break;
}
return answ;
}
private async Task OnDialogClose(bool accepted)
{
DeleteDialogOpen = false;
currPage = 1;
await AsyncReload();
//StateHasChanged();
}
private void OpenDialog()
{
DeleteDialogOpen = true;
StateHasChanged();
}
#endregion Private Methods
#region Protected Methods
protected async Task AsyncReload()
{
isLoading = true;
currRecord = null;
ListRecords = null;
await ReloadData();
isLoading = false;
}
protected void Edit(FileModel selRecord)
{
// rileggo dal DB il record corrente...
var pUpd = Task.Run(async () => currRecord = await DataService.FileGetByKey(selRecord.FileId));
pUpd.Wait();
}
protected async Task FilterPath(string searchVal)
{
SelFileName = searchVal;
OnlyActive = false;
await ReloadAllData();
isLoading = false;
}
protected async Task FilterTag(string searchVal)
{
SelTag = searchVal;
await ReloadAllData();
isLoading = false;
}
protected async Task ForceCheck(int numDays)
{
currRecord = null;
ListRecords = null;
// importante altrimenti NON mostra update UI
await Task.Delay(1);
//AppMService.File_Filter = SelectData.Init(5, 10);
var numCheck = await DataService.updateAllArchive(numDays, false);
await ReloadAllData();
await Task.Delay(1);
await RefreshDisplayLoading();
}
protected override async Task OnInitializedAsync()
{
SearchTag = defTag;
AppMService.ShowSearch = true;
AppMService.PageName = "Archivio File Programmi";
AppMService.PageIcon = "fas fa-folder pr-2";
AppMService.EA_SearchUpdated += OnSeachUpdated;
AppMService.EA_FilterUpdated += OnFilterUpdated;
await ReloadAllData();
isLoading = false;
}
protected async Task PagerReloadNum(int newNum)
{
numRecord = newNum;
await ReloadData();
isLoading = false;
}
protected async Task PagerReloadPage(int newNum)
{
currPage = newNum;
await ReloadData();
isLoading = false;
}
protected async Task RefreshDisplayLoading()
{
await Task.Delay(1);
isLoading = false;
}
protected async Task ReloadAllData()
{
isLoading = true;
MacList = await DataService.MacchineGetAll();
SelIdxMacc = "0";
SearchTag = defTag;
TagList = await DataService.TagGetFilt(SearchTag);
await ReloadData();
}
protected async Task ReloadData()
{
isLoading = true;
// importante altrimenti NON mostra update UI
await Task.Delay(1);
totalCount = await DataService.FileCountFilt(AppMService.File_Filter);
//SearchRecords = await DataService.FileGetFilt(AppMService.File_Filter);
//// faccio paginazione SOLO NELLA DECINA attuale... (quindi non tutte le pagine ma solo subset)
//ListRecords = SearchRecords.Skip(numRecord * (currPage % 10 - 1)).Take(numRecord).ToList();
ListRecords = await DataService.FileGetFilt(AppMService.File_Filter);
await Task.Delay(1);
}
protected void ResetData()
{
DataService.rollBackEdit(currRecord);
currRecord = null;
}
protected async Task ResetFilter()
{
currRecord = null;
ListRecords = null;
AppMService.File_Filter = SelectData.Init(5, 10);
AppMService.SearchVal = "";
SearchTag = defTag;
await ReloadAllData();
isLoading = false;
}
protected void ResetSearchTag()
{
SearchTag = defTag;
}
protected void Select(FileModel selRecord)
{
// applico filtro da selezione
currRecord = selRecord;
}
protected async Task UpdateData()
{
currRecord = null;
ListRecords = null;
DataService.ResetController();
await ReloadData();
await Task.Delay(1);
isLoading = false;
}
#endregion Protected Methods
#region Public Methods
public string checkSelect(int FileId)
{
string answ = "";
if (currRecord != null)
{
try
{
answ = (currRecord.FileId == FileId) ? "table-info" : "";
}
catch
{ }
}
return answ;
}
public void Dispose()
{
AppMService.EA_SearchUpdated -= OnSeachUpdated;
AppMService.EA_FilterUpdated -= OnFilterUpdated;
}
public async void OnFilterUpdated()
{
await ReloadData();
//StateHasChanged();
}
public async void OnSeachUpdated()
{
SearchVal = AppMService.SearchVal;
//await ReloadData();
StateHasChanged();
}
public void ResetTag()
{
SelTag = "";
}
#endregion Public Methods
}
}
+42
View File
@@ -0,0 +1,42 @@
@page
@model MP.Prog.Pages.ErrorModel
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>Error</title>
<link href="~/css/bootstrap/bootstrap.min.css" rel="stylesheet" />
<link href="~/css/app.css" rel="stylesheet" />
</head>
<body>
<div class="main">
<div class="content px-4">
<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>
@if (Model.ShowRequestId)
{
<p>
<strong>Request ID:</strong> <code>@Model.RequestId</code>
</p>
}
<h3>Development Mode</h3>
<p>
Swapping to the <strong>Development</strong> environment displays detailed information about the error that occurred.
</p>
<p>
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
It can result in displaying sensitive information from exceptions to end users.
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
and restarting the app.
</p>
</div>
</div>
</body>
</html>
+32
View File
@@ -0,0 +1,32 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
namespace MP.Prog.Pages
{
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
[IgnoreAntiforgeryToken]
public class ErrorModel : PageModel
{
public string RequestId { get; set; }
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
private readonly ILogger<ErrorModel> _logger;
public ErrorModel(ILogger<ErrorModel> logger)
{
_logger = logger;
}
public void OnGet()
{
RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
}
}
}
+57
View File
@@ -0,0 +1,57 @@
@page "/"
@using MP.Prog.Data
@inject MessageService AppMService
<div class="jumbotron py-4">
<div class="row">
<div class="col-12 col-lg-4">
<h1>MAPO Prog</h1>
<div>
Gestione archivio programmi macchina per MES 4.0
</div>
</div>
<div class="col-12 col-lg-8 text-right">
<div class="text-light h1 d-none d-md-block">
<span class="fas fa-home" aria-hidden="true"></span> | <span class="fas fa-folder" aria-hidden="true"></span> | <span class="fas fa-wrench" aria-hidden="true"></span>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-12 my-lg-5">
@*<SetupDiagnostics></SetupDiagnostics>*@
</div>
<div class="col-12 text-center">
<div class="row">
<div class="col-4"></div>
<div class="col-4">
<i class="fas fa-code-branch fa-5x"></i>
</div>
<div class="col-4"></div>
</div>
<h4>
Sistema di gestione ed archiviazione storica dei programmi macchina CNC.
</h4>
</div>
<div class="col-12 text-center mt-5">
<div class="col-4"></div>
<div class="col-4"></div>
<div class="col-4 badge badge-pill badge-dark">
<div class="px-1">
<a class="text-light" href="https://www.egalware.com/" target="_blank">powered by&nbsp;EgalWare <img width="24" class="img-fluid" src="img/LogoBlu.svg" /></a>
</div>
</div>
</div>
</div>
@code
{
protected override void OnInitialized()
{
AppMService.ShowSearch = false;
AppMService.PageName = "Home";
AppMService.PageIcon = "fas fa-home pr-2";
}
}
+17
View File
@@ -0,0 +1,17 @@
@page "/Setup"
@using MP.Prog.Data
@using System.Text
@using DiffMatchPatch
@inject MessageService AppMService
<div class="card">
<div class="card-header">
<h4>Setup</h4>
</div>
<div class="card-body">
<MP.Prog.Components.ArchiveStatus></MP.Prog.Components.ArchiveStatus>
</div>
@*<div class="card-footer">Footer</div>*@
</div>
+21
View File
@@ -0,0 +1,21 @@
using Microsoft.AspNetCore.Components;
using MP.Prog.Data;
using System;
using System.Threading.Tasks;
namespace MP.Prog.Pages
{
public partial class Setup : ComponentBase
{
#region Protected Methods
protected override void OnInitialized()
{
AppMService.ShowSearch = false;
AppMService.PageName = "Setup";
AppMService.PageIcon = "fas fa-wrench pr-2";
}
#endregion Protected Methods
}
}
+28
View File
@@ -0,0 +1,28 @@
@page "/Test"
@using Majorsoft.Blazor.Components.Debounce
<h3>Test</h3>
<DebounceInput id="in1" class="form-control w-100" placeholder="@("Digitare almeno " + _minCharsLength + " caratteri")" autocomplete="off"
@ref="input1"
@bind-Value="@_debounceInputValue" @bind-Value:event="OnInput"
DebounceTime="@_debounceMilisec"
MinLength="@_minCharsLength"
OnValueChanged="e => { _notifiedInputValue = e; }"
ForceNotifyByEnter="@_forceNotifyByEnter"
ForceNotifyOnBlur="@_forceNotifyOnBlur" />
<div>Notified value: @_notifiedInputValue</div>
<div>Actual value: @_debounceInputValue</div>
<input type="button" class="btn btn-primary" value="Read out actual value" @onclick="(_ => { _debounceInputValue = input1.Value; })" />
@code {
//DebounceInput
private string _debounceInputValue = "";
private string _notifiedInputValue = "";
private int _debounceMilisec = 200;
private int _minCharsLength = 2;
private bool _forceNotifyByEnter = true;
private bool _forceNotifyOnBlur = true;
private DebounceInput input1;
}
+47
View File
@@ -0,0 +1,47 @@
@page "/"
@using System.Globalization
@using Microsoft.AspNetCore.Localization
@namespace MP.Prog.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
Layout = null;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="mobile-web-app-capable" content="yes">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>MP.Prog</title>
<base href="~/" />
<link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css" />
<link rel="stylesheet" href="font-awesome/css/fontawesome.min.css" />
<link href="css/site.css" rel="stylesheet" />
<link href="MP.Prog.styles.css" rel="stylesheet" />
</head>
<body>
<component type="typeof(App)" render-mode="ServerPrerendered" />
<div id="blazor-error-ui">
<environment include="Staging,Production">
An error has occurred. This application may no longer respond until reloaded.
</environment>
<environment include="Development">
An unhandled exception has occurred. See browser dev tools for details.
</environment>
<a href="" class="reload">Reload</a>
<a class="dismiss">🗙</a>
</div>
<!-- inside of body section and after the div/app tag -->
<script src="jquery/jquery.min.js"></script>
<script src="popper.js/umd/popper.min.js"></script>
<script src="bootstrap/js/bootstrap.min.js"></script>
<script src="font-awesome/js/all.min.js"></script>
<script src="_framework/blazor.server.js"></script>
</body>
</html>
+54
View File
@@ -0,0 +1,54 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using NLog.Web;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace MP.Prog
{
public class Program
{
#region Public Methods
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
})
.ConfigureLogging(logging =>
{
logging.ClearProviders();
logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
})
.UseNLog();
public static void Main(string[] args)
{
// inclusione NLog:
// https://github.com/NLog/NLog/wiki/Getting-started-with-ASP.NET-Core-5
// https://codewithmukesh.com/blog/logging-with-nlog-in-aspnet-core/
var logger = NLog.Web.NLogBuilder.ConfigureNLog("NLog.config").GetCurrentClassLogger();
try
{
logger.Info("MP.Prog Application Starting Up");
CreateHostBuilder(args).Build().Run();
}
catch (Exception exception)
{
logger.Error(exception, "Stopped MP.Prog program because of exception");
throw;
}
finally
{
NLog.LogManager.Shutdown();
}
}
#endregion Public Methods
}
}
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<DeleteExistingFiles>False</DeleteExistingFiles>
<ExcludeApp_Data>False</ExcludeApp_Data>
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<PublishProvider>FileSystem</PublishProvider>
<PublishUrl>bin\publish\net5.0\</PublishUrl>
<WebPublishMethod>FileSystem</WebPublishMethod>
</PropertyGroup>
</Project>
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is used by the publish/package process of your Web project. You can customize the behavior of this process
by editing this MSBuild file. In order to learn more about this please visit https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>MSDeploy</WebPublishMethod>
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish>
</SiteUrlToLaunchAfterPublish>
<ExcludeApp_Data>False</ExcludeApp_Data>
<ProjectGuid>d9901b50-e61c-400c-b62c-fa060cf72c29</ProjectGuid>
<SelfContained>false</SelfContained>
<MSDeployServiceURL>https://IIS01:8172/MsDeploy.axd</MSDeployServiceURL>
<DeployIisAppPath>Default Web Site/MP/PROG</DeployIisAppPath>
<RemoteSitePhysicalPath />
<SkipExtraFilesOnServer>False</SkipExtraFilesOnServer>
<MSDeployPublishMethod>WMSVC</MSDeployPublishMethod>
<EnableMSDeployBackup>True</EnableMSDeployBackup>
<UserName>jenkins</UserName>
<_SavePWD>True</_SavePWD>
<TargetFramework>net5.0</TargetFramework>
<EnableMsDeployAppOffline>True</EnableMsDeployAppOffline>
</PropertyGroup>
</Project>
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is used by the publish/package process of your Web project. You can customize the behavior of this process
by editing this MSBuild file. In order to learn more about this please visit https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>MSDeploy</WebPublishMethod>
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish>
</SiteUrlToLaunchAfterPublish>
<ExcludeApp_Data>False</ExcludeApp_Data>
<ProjectGuid>d9901b50-e61c-400c-b62c-fa060cf72c29</ProjectGuid>
<SelfContained>false</SelfContained>
<MSDeployServiceURL>https://IIS02:8172/MsDeploy.axd</MSDeployServiceURL>
<DeployIisAppPath>Default Web Site/MP/PROG</DeployIisAppPath>
<RemoteSitePhysicalPath />
<SkipExtraFilesOnServer>False</SkipExtraFilesOnServer>
<MSDeployPublishMethod>WMSVC</MSDeployPublishMethod>
<EnableMSDeployBackup>True</EnableMSDeployBackup>
<UserName>jenkins</UserName>
<_SavePWD>True</_SavePWD>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
</Project>
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is used by the publish/package process of your Web project. You can customize the behavior of this process
by editing this MSBuild file. In order to learn more about this please visit https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>Package</WebPublishMethod>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish />
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
<ExcludeApp_Data>False</ExcludeApp_Data>
<ProjectGuid>d9901b50-e61c-400c-b62c-fa060cf72c29</ProjectGuid>
<DesktopBuildPackageLocation>bin\publish\MP.Prog.zip</DesktopBuildPackageLocation>
<PackageAsSingleFile>true</PackageAsSingleFile>
<DeployIisAppPath>Default Web Site/MP/PROG</DeployIisAppPath>
<TargetFramework>net5.0</TargetFramework>
<SelfContained>false</SelfContained>
</PropertyGroup>
</Project>
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is used by the publish/package process of your Web project. You can customize the behavior of this process
by editing this MSBuild file. In order to learn more about this please visit https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>MSDeploy</WebPublishMethod>
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish>
</SiteUrlToLaunchAfterPublish>
<ExcludeApp_Data>False</ExcludeApp_Data>
<ProjectGuid>d9901b50-e61c-400c-b62c-fa060cf72c29</ProjectGuid>
<SelfContained>false</SelfContained>
<MSDeployServiceURL>https://w2019-iis-dev:8172/MsDeploy.axd</MSDeployServiceURL>
<DeployIisAppPath>Default Web Site/MP/PROG</DeployIisAppPath>
<RemoteSitePhysicalPath />
<SkipExtraFilesOnServer>False</SkipExtraFilesOnServer>
<MSDeployPublishMethod>WMSVC</MSDeployPublishMethod>
<EnableMSDeployBackup>True</EnableMSDeployBackup>
<UserName>jenkins</UserName>
<_SavePWD>True</_SavePWD>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
</Project>
+28
View File
@@ -0,0 +1,28 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:7312",
"sslPort": 44309
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"MP.Prog": {
"commandName": "Project",
"dotnetRunMessages": "true",
"launchBrowser": true,
"applicationUrl": "https://localhost:5001;http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
+27
View File
@@ -0,0 +1,27 @@
<body>
<i>Modulo gestione Programmi 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 gestione Programmi MAPO</i>
<h4>Versione: 1.1.2109.1612</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.1.2109.1612

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

+7
View File
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<item>
<version>1.1.2109.1612</version>
<url>http://nexus.steamware.net/repository/SWS/MP-PROG/stable/0/MP.Prog.zip</url>
<changelog>http://nexus.steamware.net/repository/SWS/MP-PROG/stable/0/ChangeLog.html</changelog>
<mandatory>false</mandatory>
</item>
+63
View File
@@ -0,0 +1,63 @@
@inherits LayoutComponentBase
@using MP.Prog.Data
@using MP.Prog.Components
@inject MessageService AppMService
@implements IDisposable
<div class="page">
<div class="sidebar">
<NavMenu />
</div>
<CascadingValue Name="ShowSearch" Value=@ShowSearch>
<div class="main mr-1">
<div class="top-row">
<CmpTop></CmpTop>
</div>
<div class="content pt-1 pt-lg-2 mb-5">
@Body
</div>
<div class="fixed-bottom bottom-row">
<CmpFooter></CmpFooter>
</div>
</div>
</CascadingValue>
</div>
@code {
bool ShowSearch { get; set; } = false;
protected override void OnInitialized()
{
AppMService.EA_ShowSearch += OnShowSearch;
AppMService.EA_HideSearch += OnHideSearch;
}
public void OnShowSearch()
{
ShowSearch = true;
InvokeAsync(() =>
{
StateHasChanged();
});
}
public void OnHideSearch()
{
ShowSearch = false;
InvokeAsync(() =>
{
StateHasChanged();
});
}
public void Dispose()
{
AppMService.EA_ShowSearch -= OnShowSearch;
AppMService.EA_ShowSearch -= OnHideSearch;
}
}
+78
View File
@@ -0,0 +1,78 @@
.page {
position: relative;
display: flex;
flex-direction: column;
}
.main {
flex: 1;
}
.sidebar, .sidebarSmall {
background-image: linear-gradient(180deg, rgb(5, 39, 103) 20%, #3aa6ff 90%);
}
.top-row {
background-color: #f7f7f7;
border-bottom: 1px solid #d6d5d5;
height: 3.5rem;
align-items: center;
/*justify-content: space-evenly;
display: flex;*/
}
.top-row ::deep a, .top-row .btn-link {
white-space: nowrap;
margin-left: 1.5rem;
}
.top-row a:first-child {
overflow: hidden;
text-overflow: ellipsis;
}
.bottom-row {
color: #dedede;
background-color: #000000;
height: 2rem;
align-items: center;
}
@media (min-width: 641px) {
.page {
flex-direction: row;
}
.sidebar {
width: 250px;
height: 100vh;
position: sticky;
top: 0;
}
.sidebarSmall {
width: 80px;
height: 100vh;
position: sticky;
top: 0;
}
.top-row {
position: sticky;
top: 0;
z-index: 1;
}
.bottom-row {
position: fixed;
bottom: 0;
z-index: 1;
}
.main > div {
padding-left: 0.5rem !important;
padding-right: 0.5rem !important;
/*padding-left: 2rem !important;
padding-right: 1.5rem !important;*/
}
}
+37
View File
@@ -0,0 +1,37 @@
<div class="top-row pl-4 navbar navbar-dark">
<a class="navbar-brand" href="">MP.Prog</a>
<button class="navbar-toggler" @onclick="ToggleNavMenu">
<span class="navbar-toggler-icon"></span>
</button>
</div>
<div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
<ul class="nav flex-column">
<li class="nav-item px-3">
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
<span class="fas fa-home fa-2x pr-2" aria-hidden="true"></span> Home
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="Archive">
<span class="far fa-folder fa-2x pr-2" aria-hidden="true"></span> Archivio File
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="Setup">
<span class="fas fa-wrench fa-2x pr-2" aria-hidden="true"></span> Setup
</NavLink>
</li>
</ul>
</div>
@code {
private bool collapseNavMenu = true;
private string NavMenuCssClass => collapseNavMenu ? "collapse" : null;
private void ToggleNavMenu()
{
collapseNavMenu = !collapseNavMenu;
}
}
+62
View File
@@ -0,0 +1,62 @@
.navbar-toggler {
background-color: rgba(255, 255, 255, 0.1);
}
.top-row {
height: 3.5rem;
background-color: rgba(0,0,0,0.4);
}
.navbar-brand {
font-size: 1.1rem;
}
.oi {
width: 2rem;
font-size: 1.1rem;
vertical-align: text-top;
top: -2px;
}
.nav-item {
font-size: 0.9rem;
padding-bottom: 0.5rem;
}
.nav-item:first-of-type {
padding-top: 1rem;
}
.nav-item:last-of-type {
padding-bottom: 1rem;
}
.nav-item ::deep a {
color: #d7d7d7;
border-radius: 4px;
height: 3rem;
display: flex;
align-items: center;
line-height: 3rem;
}
.nav-item ::deep a.active {
background-color: rgba(255,255,255,0.25);
color: white;
}
.nav-item ::deep a:hover {
background-color: rgba(255,255,255,0.1);
color: white;
}
@media (min-width: 641px) {
.navbar-toggler {
display: none;
}
.collapse {
/* Never collapse the sidebar for wide screens */
display: block;
}
}
+233
View File
@@ -0,0 +1,233 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Localization;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using MP.Prog.Data;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading.Tasks;
namespace MP.Prog
{
public class Startup
{
#region Public Constructors
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
#endregion Public Constructors
#region Public Properties
public IConfiguration Configuration { get; }
#endregion Public Properties
#region Public Methods
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
//app.UseMigrationsEndPoint();
}
else
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
// cultura IT...
var supportedCultures = new[]{
new CultureInfo("it-IT")
};
app.UseRequestLocalization(new RequestLocalizationOptions
{
DefaultRequestCulture = new RequestCulture("it-IT"),
SupportedCultures = supportedCultures,
FallBackToParentCultures = false
});
CultureInfo.DefaultThreadCurrentCulture = CultureInfo.CreateSpecificCulture("it-IT");
//// Registrazione Elmah:
//// https://github.com/ElmahCore/ElmahCore
//app.UseElmah();
// fix forwarders
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
//app.UseAuthentication();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
//app.UseAuthentication();
//app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
//endpoints.MapControllers();
endpoints.MapBlazorHub();
//endpoints.MapHealthChecksUI();
//endpoints.MapHealthChecks("/health", new HealthCheckOptions
//{
// Predicate = _ => true,
// ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
//});
endpoints.MapFallbackToPage("/_Host");
});
}
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
#if false
// init info x DB
string dbServerAddr = Configuration["DbConfig:Server"];
string nKey = Configuration["DbConfig:nKey"];
string sKey = Configuration["DbConfig:sKey"];
DbConfig.InitDb(dbServerAddr, nKey, sKey);
// inizializzo il DB e creo (se necessario) l'utente
DbConfig.CheckUser(nKey, sKey);
// verifico se serve applicazione migrazioni
//DbConfig.ExecMigrationMain();
//DbConfig.ExecMigrationIdentity();
// altri parametri per check vari
string connStringDB = DbConfig.CONNECTION_STRING;
string connStringRedis = Configuration.GetConnectionString("Redis");
string redisSrvAddr = connStringRedis.Substring(0, connStringRedis.IndexOf(":"));
//var qrCodeUri = new Uri(Configuration["ZCodeUrl"]);
//string qrCodeAddr = qrCodeUri.Host;
#endif
#if false
// healthchecks
services.AddHealthChecks()
.AddMySql(connStringDB, "MySql instance")
.AddAsyncCheck($"DB PING ({dbServerAddr})", () => Health.Checks.PingCheck(dbServerAddr))
.AddAsyncCheck($"Redis PING ({redisSrvAddr})", () => Health.Checks.PingCheck(redisSrvAddr))
//.AddAsyncCheck($"QrCode PING ({qrCodeAddr})", () => Health.Checks.PingCheck(qrCodeAddr))
.AddProcessAllocatedMemoryHealthCheck(512, "Max Process memory (<512MB)", failureStatus: HealthStatus.Degraded) // 512 MB max allocated memory
.AddRedis(Configuration.GetConnectionString("Redis"), "Redis", failureStatus: HealthStatus.Degraded)
//.AddUrlGroup(new Uri(Configuration["ZCodeUrl"]), name: $"QrCode Gen ({Configuration["ZCodeUrl"]})", failureStatus: HealthStatus.Degraded)
.AddAsyncCheck($"MySql Root User", () => Health.Checks.DbUserRoot("MySql"))
.AddAsyncCheck($"MySql App Users", () => Health.Checks.DbUserApp(DbConfig.DATABASE_NAME))
.AddAsyncCheck($"MySql Identity", () => Health.Checks.DbIdentity(DbConfig.DATABASE_NAME))
.AddAsyncCheck($"MySql PlantLog", () => Health.Checks.DbPlantLogTable(DbConfig.DATABASE_NAME))
;
//.AddDiskStorageHealthCheck(s => s.AddDrive("C:\\", 1024)) // 1024 MB (1 GB) free minimum
//.AddProcessHealthCheck("ProcessName", p => p.Length > 0) // check if process is running
//.AddWindowsServiceHealthCheck("someservice", s => s.Status == ServiceControllerStatus.Running);
services
.AddHealthChecksUI(s =>
{
s.AddHealthCheckEndpoint("GWMS_Services", "health");
s.SetEvaluationTimeInSeconds(60);
s.SetMinimumSecondsBetweenFailureNotifications(120);
s.SetApiMaxActiveRequests(5);
s.SetHeaderText("GWMS Health Check Status");
})
.AddInMemoryStorage();
// abilitazione x email management con MailKit
services.AddTransient<IEmailSender, MailKitEmailSender>();
services.Configure<MailKitEmailSenderOptions>(options =>
{
options.Host_Address = Configuration["ExternalProviders:MailKit:SMTP:Address"];
options.Host_Port = Convert.ToInt32(Configuration["ExternalProviders:MailKit:SMTP:Port"]);
options.Host_Username = Configuration["ExternalProviders:MailKit:SMTP:Account"];
options.Host_Password = Configuration["ExternalProviders:MailKit:SMTP:Password"];
options.Sender_EMail = Configuration["ExternalProviders:MailKit:SMTP:SenderEmail"];
options.Sender_Name = Configuration["ExternalProviders:MailKit:SMTP:SenderName"];
});
#endif
// cookie applicazione da 14 gg (defaul) a 30
services.ConfigureApplicationCookie(o =>
{
o.ExpireTimeSpan = TimeSpan.FromDays(30);
o.SlidingExpiration = true;
});
#if false
// token di sicurezza dati a 3h
services.Configure<DataProtectionTokenProviderOptions>(o =>
o.TokenLifespan = TimeSpan.FromHours(3));
#endif
#if false
// setup MySql
//string connString = Configuration.GetConnectionString("AdminConnection");
var serverVersion = DbConfig.MysqlServerVersion(connStringDB);
services.AddDbContext<UserIdentityDbContext>(options =>
options.UseMySql(connStringDB, serverVersion));
// identity management
services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddRoles<IdentityRole>()
.AddEntityFrameworkStores<UserIdentityDbContext>();
#endif
#if false
services.AddBlazorise(options =>
{
options.ChangeTextOnKeyPress = true; // optional
})
.AddBootstrapProviders()
.AddFontAwesomeIcons();
#endif
//// Elmah
//services.AddElmah();
//string elmaConn = "Data Source=SQL2016DEV;Initial Catalog=Elmah;User ID=sa;Password=keyhammer16;integrated security=False;MultipleActiveResultSets=True;App=SHERPA.BBM;";
//services.AddElmah<SqlErrorLog>(options =>
//{
// options.ConnectionString = elmaConn;
//});
services.AddStackExchangeRedisCache(options =>
{
//options.Configuration = "localhost:6379";
options.ConfigurationOptions = new StackExchange.Redis.ConfigurationOptions() { KeepAlive = 180, DefaultDatabase = 5, EndPoints = { { "localhost", 6379 } } };
options.InstanceName = "MP:Prog";
});
services.AddLocalization();
services.AddRazorPages();
services.AddServerSideBlazor();
#if false
services.AddScoped<AuthenticationStateProvider, RevalidatingIdentityAuthenticationStateProvider<IdentityUser>>();
services.AddDatabaseDeveloperPageExceptionFilter();
#endif
services.AddSingleton<IConfiguration>(Configuration);
//services.AddTransient<Services.BlazorTimer>();
//services.AddSingleton<FileArchDataService>();
services.AddScoped<FileArchDataService>();
services.AddScoped<MessageService>();
}
#endregion Public Methods
}
}
+10
View File
@@ -0,0 +1,10 @@
@using System.Net.Http
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.Authorization
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.JSInterop
@using MP.Prog
@using MP.Prog.Shared
+10
View File
@@ -0,0 +1,10 @@
{
//"DetailedErrors": true,
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
}
}
+15
View File
@@ -0,0 +1,15 @@
{
"DetailedErrors": true,
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"DefaultConnection": "Server=localhost\\SQLEXPRESS;Database=MoonPro_PROG;Trusted_Connection=True;MultipleActiveResultSets=true",
"Mp.Prog": "Server=localhost\\SQLEXPRESS;Database=MoonPro_PROG;User ID=sa;Password=keyhammer16;integrated security=False;MultipleActiveResultSets=True;App=MP.PROG;"
}
}
+15
View File
@@ -0,0 +1,15 @@
{
"DetailedErrors": true,
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"DefaultConnection": "Server=SQL2016DEV;Database=MoonPro_PROG;Trusted_Connection=True;MultipleActiveResultSets=true",
"Mp.Prog": "Server=SQL2016DEV;Database=MoonPro_PROG;User ID=sa;Password=keyhammer16;integrated security=False;MultipleActiveResultSets=True;App=MP.PROG;"
}
}
+22
View File
@@ -0,0 +1,22 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
//"LogLevel": {
// "Default": "Debug",
// "Microsoft": "Information",
// "Microsoft.AspNetCore.SignalR": "Debug",
// "Microsoft.AspNetCore.Http.Connections": "Debug",
// "System": "Information"
//}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"DefaultConnection": "Server=SQL2016DEV;Database=MoonPro_PROG;Trusted_Connection=True;MultipleActiveResultSets=true",
"Mp.Prog": "Server=SQL2016DEV;Database=MoonPro_PROG;User ID=sa;Password=keyhammer16;integrated security=False;MultipleActiveResultSets=True;App=MP.Prog;",
"Redis": "localhost:6379"
}
}
+8
View File
@@ -0,0 +1,8 @@
[
{
"outputFileName": "wwwroot/bootstrap/css/bootstrap.min.css",
"inputFiles": [
"wwwroot/bootstrap/css/bootstrap.css"
]
}
]
+10
View File
@@ -0,0 +1,10 @@
[
{
"outputFile": "wwwroot/css/font.css",
"inputFile": "wwwroot/css/font.less"
},
{
"outputFile": "wwwroot/css/site.css",
"inputFile": "wwwroot/css/site.less"
}
]
+22
View File
@@ -0,0 +1,22 @@
{
"version": "1.0",
"defaultProvider": "cdnjs",
"libraries": [
{
"library": "font-awesome@5.15.4",
"destination": "wwwroot/font-awesome/"
},
{
"library": "bootstrap@4.6.0",
"destination": "wwwroot/bootstrap/"
},
{
"library": "popper.js@1.16.1",
"destination": "wwwroot/popper.js/"
},
{
"library": "jquery@3.5.1",
"destination": "wwwroot/jquery/"
}
]
}
+1
View File
@@ -0,0 +1 @@

+34
View File
@@ -0,0 +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.1."
$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 $FileVers -Value $currRelNum
# replace x manifest
$manData = Get-Content $FileManIn
$manData = $manData -replace "1.0.0.0", $currRelNum
$manData = $manData -replace "{{DIRNAME}}", "MP-PROG"
$manData = $manData -replace "{{BRANCHNAME}}", "stable/0"
$manData = $manData -replace "{{PACKNAME}}", "MP.Prog"
Set-Content -Path $FileManOut -Value $manData
# replace x ChangeLog
$clogData = Get-Content $FileCLogIn
$clogData = $clogData -replace "{{CURRENT-REL}}", $currRelNum
# $clogData = $clogData -replace "{{DIRNAME}}", "MP-PROG"
# $clogData = $clogData -replace "{{BRANCHNAME}}", "stable"
# $clogData = $clogData -replace "{{PACKNAME}}", "MP.Prog"
Set-Content -Path $FileCLogOut -Value $clogData
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
+325
View File
@@ -0,0 +1,325 @@
/*!
* Bootstrap Reboot v4.6.0 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors
* Copyright 2011-2021 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/
*,
*::before,
*::after {
box-sizing: border-box;
}
html {
font-family: sans-serif;
line-height: 1.15;
-webkit-text-size-adjust: 100%;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
article, aside, figcaption, figure, footer, header, hgroup, main, nav, section {
display: block;
}
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
font-size: 1rem;
font-weight: 400;
line-height: 1.5;
color: #212529;
text-align: left;
background-color: #fff;
}
[tabindex="-1"]:focus:not(:focus-visible) {
outline: 0 !important;
}
hr {
box-sizing: content-box;
height: 0;
overflow: visible;
}
h1, h2, h3, h4, h5, h6 {
margin-top: 0;
margin-bottom: 0.5rem;
}
p {
margin-top: 0;
margin-bottom: 1rem;
}
abbr[title],
abbr[data-original-title] {
text-decoration: underline;
-webkit-text-decoration: underline dotted;
text-decoration: underline dotted;
cursor: help;
border-bottom: 0;
-webkit-text-decoration-skip-ink: none;
text-decoration-skip-ink: none;
}
address {
margin-bottom: 1rem;
font-style: normal;
line-height: inherit;
}
ol,
ul,
dl {
margin-top: 0;
margin-bottom: 1rem;
}
ol ol,
ul ul,
ol ul,
ul ol {
margin-bottom: 0;
}
dt {
font-weight: 700;
}
dd {
margin-bottom: .5rem;
margin-left: 0;
}
blockquote {
margin: 0 0 1rem;
}
b,
strong {
font-weight: bolder;
}
small {
font-size: 80%;
}
sub,
sup {
position: relative;
font-size: 75%;
line-height: 0;
vertical-align: baseline;
}
sub {
bottom: -.25em;
}
sup {
top: -.5em;
}
a {
color: #007bff;
text-decoration: none;
background-color: transparent;
}
a:hover {
color: #0056b3;
text-decoration: underline;
}
a:not([href]):not([class]) {
color: inherit;
text-decoration: none;
}
a:not([href]):not([class]):hover {
color: inherit;
text-decoration: none;
}
pre,
code,
kbd,
samp {
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
font-size: 1em;
}
pre {
margin-top: 0;
margin-bottom: 1rem;
overflow: auto;
-ms-overflow-style: scrollbar;
}
figure {
margin: 0 0 1rem;
}
img {
vertical-align: middle;
border-style: none;
}
svg {
overflow: hidden;
vertical-align: middle;
}
table {
border-collapse: collapse;
}
caption {
padding-top: 0.75rem;
padding-bottom: 0.75rem;
color: #6c757d;
text-align: left;
caption-side: bottom;
}
th {
text-align: inherit;
text-align: -webkit-match-parent;
}
label {
display: inline-block;
margin-bottom: 0.5rem;
}
button {
border-radius: 0;
}
button:focus:not(:focus-visible) {
outline: 0;
}
input,
button,
select,
optgroup,
textarea {
margin: 0;
font-family: inherit;
font-size: inherit;
line-height: inherit;
}
button,
input {
overflow: visible;
}
button,
select {
text-transform: none;
}
[role="button"] {
cursor: pointer;
}
select {
word-wrap: normal;
}
button,
[type="button"],
[type="reset"],
[type="submit"] {
-webkit-appearance: button;
}
button:not(:disabled),
[type="button"]:not(:disabled),
[type="reset"]:not(:disabled),
[type="submit"]:not(:disabled) {
cursor: pointer;
}
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
padding: 0;
border-style: none;
}
input[type="radio"],
input[type="checkbox"] {
box-sizing: border-box;
padding: 0;
}
textarea {
overflow: auto;
resize: vertical;
}
fieldset {
min-width: 0;
padding: 0;
margin: 0;
border: 0;
}
legend {
display: block;
width: 100%;
max-width: 100%;
padding: 0;
margin-bottom: .5rem;
font-size: 1.5rem;
line-height: inherit;
color: inherit;
white-space: normal;
}
progress {
vertical-align: baseline;
}
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
height: auto;
}
[type="search"] {
outline-offset: -2px;
-webkit-appearance: none;
}
[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
::-webkit-file-upload-button {
font: inherit;
-webkit-appearance: button;
}
output {
display: inline-block;
}
summary {
display: list-item;
cursor: pointer;
}
template {
display: none;
}
[hidden] {
display: none !important;
}
/*# sourceMappingURL=bootstrap-reboot.css.map */
File diff suppressed because one or more lines are too long
@@ -0,0 +1,8 @@
/*!
* Bootstrap Reboot v4.6.0 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors
* Copyright 2011-2021 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus:not(:focus-visible){outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([class]){color:inherit;text-decoration:none}a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit;text-align:-webkit-match-parent}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}
/*# sourceMappingURL=bootstrap-reboot.min.css.map */
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
File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More