Compare commits

..

172 Commits

Author SHA1 Message Date
Samuele Locatelli e945aad224 Merge branch 'Release/FirstSpecStableRelease' 2022-09-21 10:36:40 +02:00
Samuele Locatelli 8510731366 Update home page 2022-09-21 10:36:29 +02:00
Samuele Locatelli 5df4195e6c Completato salvataggio snapshot + refresh 2022-09-21 10:26:09 +02:00
Samuele Locatelli a3dc1e1657 Start ver 6.16 2022-09-21 09:52:54 +02:00
Samuele Locatelli 27149e2131 Fix grafici minori 2022-09-21 09:46:44 +02:00
Samuele Locatelli 91be755781 Fix conf key redis cache:
- era overlapping parametri/dossiers
2022-09-21 09:27:00 +02:00
Samuele Locatelli 84f6730023 Merge remote-tracking branch 'origin/develop' into develop 2022-09-21 09:22:12 +02:00
zaccaria.majid b51c2679e4 aggiunta cache redis 2022-09-21 09:17:28 +02:00
zaccaria.majid 9d7502d1a4 modifiche grafiche e round orario datetime 2022-09-21 09:13:39 +02:00
zaccaria.majid d3b8160634 fix deserializzazione oggetto fluxlog 2022-09-20 17:35:45 +02:00
zaccaria.majid 601c817aa2 Modifiche grafiche 2022-09-20 17:16:42 +02:00
zaccaria.majid d0d30bd1c3 Modifiche per permettere la deserializzazione dei
valori in dossier
2022-09-20 17:16:21 +02:00
zaccaria.majid 0e9e7f3dda Creazione pagina per la visualizzazione Dossier
con relativi filtri
2022-09-20 12:54:46 +02:00
Samuele Locatelli e518c17db2 Aggiunta traccia x pagina dossiers 2022-09-20 09:03:22 +02:00
Samuele Locatelli 0a281827f9 Refresh 2022-09-19 20:01:24 +02:00
Samuele Locatelli 141473ce28 Aggiunta metodi gestione lettura dossiers da DB + refresh 2022-09-19 20:01:13 +02:00
Samuele Locatelli 45af089e3f Aggiunta preliminare modello Dossiers 2022-09-19 20:00:56 +02:00
Samuele Locatelli 4e4387620b Merge branch 'develop' of https://gitlab.steamware.net/steamware/mapo-core into develop 2022-09-19 09:58:28 +02:00
Samuele Locatelli 8c2c48a63f Fix procedura di flux dati:
- aggiunta conn tipo admin
- tolta cancellazione intero DB
- ricerca x pattern delle sole chaivi interessate
2022-09-19 09:54:30 +02:00
zaccaria.majid 534a668496 tentativo fix redis Flush 2022-09-19 09:22:29 +02:00
zaccaria.majid eed45695e8 continuo flushCache 2022-09-19 08:43:48 +02:00
zaccaria.majid ff2fbe0c34 modifiche grafiche
inizio pagina utils
2022-09-16 17:37:39 +02:00
Samuele Locatelli 3324c736c6 Minor fix 2022-09-16 16:49:19 +02:00
zaccaria.majid 0a6a0bc5cb modifiche grafiche varie 2022-09-16 16:00:13 +02:00
Samuele Locatelli e18e0ddff3 Fix last update da pagina main 2022-09-16 15:18:56 +02:00
zaccaria.majid 580a498238 tentativo fix lastUpdate 2022-09-16 14:47:31 +02:00
zaccaria.majid c97557722e Modifiche grafiche 2022-09-16 14:22:23 +02:00
zaccaria.majid c17fa17d76 fix filtri aggiunta titles 2022-09-16 12:40:18 +02:00
zaccaria.majid 5b054ee2ec fix last snapshot che non veniva
scritto al primo giro
2022-09-16 11:55:23 +02:00
zaccaria.majid 2771d9957d Merge branch 'develop' of https://gitlab.steamware.net/steamware/mapo-core into develop 2022-09-16 11:47:43 +02:00
zaccaria.majid 5893152761 aggiornamento grafico filtri 2022-09-16 11:47:35 +02:00
Samuele Locatelli b7d57e935a COmpletato fix version number 2022-09-16 11:21:03 +02:00
Samuele Locatelli 61b613a8fb Fix proj config x calcolo versione 2022-09-16 11:19:26 +02:00
Samuele Locatelli d2fef81f55 Merge remote-tracking branch 'origin/develop' into develop 2022-09-16 11:17:33 +02:00
Samuele Locatelli cd7a8ccad8 Fix x display numero versione 2022-09-16 11:17:28 +02:00
zaccaria.majid 08079d3e0e Merge branch 'develop' of https://gitlab.steamware.net/steamware/mapo-core into develop 2022-09-16 10:51:19 +02:00
zaccaria.majid 8156828ec3 fix bottone filtri avanzati 2022-09-16 10:44:45 +02:00
Samuele Locatelli 9bb95c5a49 Merge tag 'FixMasterDeploy' into develop
Fix deploy IIS x icone, errore cancellazione, log
2022-09-16 10:37:26 +02:00
Samuele Locatelli 7ba3aeb65d Merge branch 'Release/FixMasterDeploy' 2022-09-16 10:37:10 +02:00
Samuele Locatelli 6ea938a91a Aggiunta web.config x windows auth 2022-09-16 10:36:25 +02:00
Samuele Locatelli 92c196023d fix posizione img home page 2022-09-16 10:33:13 +02:00
Samuele Locatelli 10d9625b6d fix articoli:
- tolto refuso cancellazione csv temp appoggio
2022-09-16 10:33:03 +02:00
Samuele Locatelli 5f955499e2 Fix file favicon e logfolder 2022-09-16 10:32:47 +02:00
Samuele Locatelli 716813abe1 Merge tag 'AddSpecInstaller' into develop
Aggiornamento x generazione installer SPEC su nexus
2022-09-16 09:13:19 +02:00
Samuele Locatelli 6f0d0419c5 Merge branch 'Release/AddSpecInstaller' 2022-09-16 09:13:02 +02:00
Samuele Locatelli 300c2dc294 Metodo timeout+ random x cache 2022-09-16 09:03:05 +02:00
Samuele Locatelli fddfbb6dfa More cleanup! 2022-09-16 08:36:52 +02:00
Samuele Locatelli b2858c9c8a Fix catena update pagina 2022-09-16 08:16:00 +02:00
Samuele Locatelli 68404c928a Cleanup page PODL 2022-09-16 08:02:08 +02:00
Samuele Locatelli ca16c3a1b0 Clenaup classe dataAdapter 2022-09-16 08:01:51 +02:00
Samuele Locatelli c11163896c Speedup:
- aggiuta cache redis x elenco macchine con dati flux
2022-09-16 07:43:42 +02:00
Samuele Locatelli 891def5bcd refresh 2022-09-15 19:43:21 +02:00
Samuele Locatelli 65aa95d1e7 Update yaml (da testare) 2022-09-15 19:43:07 +02:00
Samuele Locatelli 1b20cd8ef5 Aggiunta xml pubblicazione 2022-09-15 19:39:31 +02:00
Samuele Locatelli 11934fcae2 Minor Update x reload 2022-09-15 19:25:51 +02:00
Samuele Locatelli 687a254a8d Collegato refresh period da edit conf 2022-09-15 18:53:51 +02:00
Samuele Locatelli 25f274d4d6 cleanup params page 2022-09-15 18:48:04 +02:00
Samuele Locatelli 0ec3a4c31a Correzione Dispose:
- fix sovrapposizione eventi multipli
2022-09-15 18:47:35 +02:00
Samuele Locatelli 1b89501529 Fix cambio pagina da cambio filtro 2022-09-15 18:35:38 +02:00
Samuele Locatelli 191b23ee7d Fix comportamento cambio filtro su pag 1 2022-09-15 18:23:10 +02:00
Samuele Locatelli ae39db267d CurrPage:
- riporto a 1 se cambio filtro
- sbaglia primo cambio da sel DataPager
2022-09-15 18:01:25 +02:00
Samuele Locatelli 7cc25ac9be Fix toggle show/hide edit params 2022-09-15 17:55:14 +02:00
Samuele Locatelli 5c30c8a1ba Levato isLoading inutilizzato da filtro parametri 2022-09-15 17:46:03 +02:00
Samuele Locatelli d5777c0020 REDIS:
- fix cache selezione flussi da macchina
- rimosse modalità async lettura/Scrittura redis
2022-09-15 17:43:52 +02:00
zaccaria.majid f5bbcae0db Aggiunta filtri per max record e
tempo aggiornamento
2022-09-15 17:28:26 +02:00
zaccaria.majid 1efd5f5a4b listParams riga 136 fix pager stop live
PARAMS riga 147 fix filter stop live
2022-09-15 16:08:47 +02:00
Samuele Locatelli 47ddab4e67 Merge branch 'Feature/TestSelFilterObj' into develop 2022-09-15 15:46:48 +02:00
Samuele Locatelli 07c58c5738 Pulizia metodi inutilizzati 2022-09-15 15:46:39 +02:00
Samuele Locatelli fcf1ec5ea9 FIX: ora ok con update in blocco 2022-09-15 15:36:05 +02:00
Samuele Locatelli 673eb62d8c Inizio gestione con unico obj filtro 2022-09-15 15:30:48 +02:00
Samuele Locatelli 6790088950 Ancora update x gestione filtro/stop live... 2022-09-15 13:09:05 +02:00
Samuele Locatelli d46f3fd38d OK con filtraggio in cascata 2022-09-15 12:40:23 +02:00
Samuele Locatelli 0fe40dacc7 Fix errore inc ascata selezione parametri 2022-09-15 12:02:01 +02:00
zaccaria.majid 0c01e93ff3 Fix filtro flussi 2022-09-15 10:51:00 +02:00
Samuele Locatelli 6da702e31f Fix dati x lettura solo macc valide (=con dati flux) 2022-09-15 10:31:39 +02:00
Samuele Locatelli ce92f70eb0 Correzione timer x considerare tempo di esecuzione 2022-09-15 09:51:24 +02:00
Samuele Locatelli 37a62a34ae Parametri:
- FIx selezione live su pagina 1
- passo a pag 1 sul cambio filtro
2022-09-15 08:57:27 +02:00
Samuele Locatelli c138ea3143 Live update:
- disattivato al cambio filtro
- sbaglia num record paginazione
2022-09-14 17:55:27 +02:00
Samuele Locatelli 4e11685415 Fix live + filtri x parameters 2022-09-14 17:49:06 +02:00
Samuele Locatelli 32398cd7fb CLeanup + tolto search da parametri 2022-09-14 17:39:29 +02:00
Samuele Locatelli d5f2ed3950 Fix lettura dati con/senza filtro 2022-09-14 17:38:16 +02:00
Samuele Locatelli f120bb6c28 Merge remote-tracking branch 'origin/Feature/ParameterDataMethods' into develop 2022-09-14 16:56:57 +02:00
zaccaria.majid 7abd135f30 Modifiche page params
aggiunta msgservice per selezione macchina
2022-09-14 16:53:46 +02:00
zaccaria.majid bae58ec4bb modifiche per grafica pagina PARAMS 2022-09-14 14:34:30 +02:00
zaccaria.majid f44838d235 Aggiunta pagina parameters con componente live. 2022-09-14 12:18:36 +02:00
zaccaria.majid 9c11e877aa Merge remote-tracking branch 'origin/develop' into Feature/ParameterDataMethods 2022-09-14 10:15:07 +02:00
zaccaria.majid 5fdd74ae9a Inizio page params 2022-09-14 10:13:51 +02:00
Samuele Locatelli b838e95c28 Merge branch 'Feature/ParameterDataMethods' into develop 2022-09-14 09:26:23 +02:00
Samuele Locatelli 0e2036cb42 Completato aggiunta metodi elenco (da testare) 2022-09-14 09:23:46 +02:00
Samuele Locatelli b29bac08a2 Inizio aggiunta parametri e metodi relativi 2022-09-14 09:07:30 +02:00
Samuele Locatelli 5559e7daa8 Fix spazio titolo x add button 2022-09-13 18:23:09 +02:00
Samuele Locatelli d3fb78810e Merge branch 'develop' of https://gitlab.steamware.net/steamware/mapo-core into develop 2022-09-13 18:20:39 +02:00
Samuele Locatelli 30dac79e7c PODL:
- completato editing con delete
2022-09-13 18:19:30 +02:00
zaccaria.majid bf8f7b8fa3 fix bottone new PODL allineato con scritta 2022-09-13 17:44:56 +02:00
zaccaria.majid 5915e5f532 Merge branch 'develop' of https://gitlab.steamware.net/steamware/mapo-core into develop 2022-09-13 17:39:54 +02:00
zaccaria.majid 658488fe0e fix bottone aggiunta PODL 2022-09-13 17:39:48 +02:00
Samuele Locatelli 5f8e60b4ba Code cleanup + fix preselezione gruppo fase + art 2022-09-13 17:35:55 +02:00
Samuele Locatelli fff3659939 Update x inserimento nuovo record (OK) 2022-09-13 17:05:08 +02:00
Samuele Locatelli 385c5cf7ea Update gestione editing fasi/key richeista 2022-09-13 16:51:13 +02:00
Samuele Locatelli 31ed8b2edb Aggiunto estrazione dato fase da PODL 2022-09-13 16:17:34 +02:00
Samuele Locatelli 0ef6d161d5 Bozza edit + new quasi OK 2022-09-13 15:44:15 +02:00
Samuele Locatelli a0b88fd157 UPdate x ricerca art in cascata 2022-09-13 15:16:46 +02:00
Samuele Locatelli ed93a04fd0 Inizio modifica selezione articolo 2022-09-13 15:01:07 +02:00
Samuele Locatelli 00a0fc81ce POSDL:
- FIX Selezione stato comemssa e filtraggio
2022-09-13 14:40:54 +02:00
Samuele Locatelli 681aa44b32 Fix reset ricerca al cambio pagina 2022-09-13 14:14:15 +02:00
zaccaria.majid 9d43a221ed fix label 2022-09-13 12:33:23 +02:00
zaccaria.majid 53a7630d97 Divisione visualizzazione ODL e PODL in due pagine 2022-09-13 12:23:44 +02:00
Samuele Locatelli 7317fa58b4 Inizio inserimento pagina PODL 2022-09-13 10:26:04 +02:00
zaccaria.majid dd56701b5b fix paginazione e ricerca 2022-09-12 16:26:30 +02:00
Samuele Locatelli 014bed96f9 Typo:
-CodeMaid vari
2022-09-12 15:12:56 +02:00
Samuele Locatelli ac196be0b7 MessageService:
- Fix errore loop infinito in update numero record totali
2022-09-12 15:12:10 +02:00
zaccaria.majid a77862b372 fix pagina PODL 2022-09-12 14:53:25 +02:00
zaccaria.majid ed5b55cf77 fix controller spec +
inizio implementazione pagina PODL
2022-09-12 13:00:34 +02:00
Samuele Locatelli aec6271f5a Update x ricerca ODL 2022-09-12 11:54:08 +02:00
Samuele Locatelli 62359ac858 Fix evento mostr/nascondi 2022-09-12 11:39:41 +02:00
Samuele Locatelli 73df595421 Fix paginazione ODL:
- aggiunto StateHasChanged in async
2022-09-12 11:28:48 +02:00
Samuele Locatelli 2cd1d57cd3 UPdate comportamento compress menù laterale sx 2022-09-12 11:14:01 +02:00
Samuele Locatelli 8934c86f7b STATS:
- Refresh conf StatsODL
2022-09-09 17:35:50 +02:00
Samuele Locatelli cee1718208 refresh list ODL 2022-08-23 11:25:58 +02:00
Samuele Locatelli 9407b451c7 bozza ODL 2022-08-01 13:34:16 +02:00
Samuele Locatelli 66469b9df7 Inizio pagina PODL/ODL correnti 2022-08-01 12:43:42 +02:00
Samuele Locatelli 57833b368d Update gestione azienda sel da config 2022-08-01 09:44:14 +02:00
Samuele Locatelli 634f5f7120 Aggiunta gestione oggetti JQM in home/index page 2022-07-25 07:56:32 +02:00
Samuele Locatelli 0e376c070c Aggiunta lettura Link JQL 2022-07-25 07:56:20 +02:00
Samuele Locatelli 387df699b0 Update link in pagina HOME 2022-07-23 17:56:51 +02:00
Samuele Locatelli 2016379205 ART:
- aggiunta ricerca x selVal
- completata ricerca veto cancellazione
2022-07-23 17:19:19 +02:00
Samuele Locatelli 0ad15c90c3 Articoli
- completato fix editing lista valori ammissibili x tipo
- ok editing
2022-07-23 16:05:38 +02:00
Samuele Locatelli 190e572bce Inizio insert listValues model 2022-07-23 12:12:54 +02:00
Samuele Locatelli 02e7b7c4e7 Modifica edit:
- azienda da selettore, tranne "tutte"
2022-07-23 11:53:38 +02:00
Samuele Locatelli e03b590844 Update pagina articoli: CRUD 2022-07-23 11:45:59 +02:00
Samuele Locatelli 4ee291c12d update bootstrap / bootstrap-icons 2022-07-23 11:45:41 +02:00
Samuele Locatelli 81c04ef70b Aggiunta metodi delete/update 2022-07-23 11:45:30 +02:00
Samuele Locatelli 19b89db170 Update display articoli 2022-07-23 10:32:35 +02:00
Samuele Locatelli 623ecd6308 Update DB
- aggiunta anagrafica aziende
- filtro articoli
2022-07-23 10:32:29 +02:00
Samuele Locatelli c5e598a0d6 Ancora update x mostrare articoli 2022-07-21 14:57:51 +02:00
Samuele Locatelli a46dc9cb32 Bozza pagine 2022-07-21 14:21:14 +02:00
Samuele Locatelli 3634f85359 Ancora update bozza SPEC 2022-07-21 11:47:33 +02:00
Samuele Locatelli 54d2cd634c Refresh sln 2022-07-21 10:05:33 +02:00
Samuele Locatelli 4cd61462c0 Aggiunta preliminare sito MP.SPEC 2022-07-21 10:05:03 +02:00
Samuele Locatelli 5444722c25 Merge tag 'AddConfMaxAge' into develop
Update impiegando MaxAge
2022-07-15 17:36:49 +02:00
Samuele Locatelli d5d47076df Merge branch 'release/AddConfMaxAge' 2022-07-15 17:36:41 +02:00
Samuele Locatelli 612c3c95f7 MON:
- fix: parametro MaxAge usato anche x redis
- cambio maxAge a 2000ms
2022-07-15 17:36:21 +02:00
Samuele Locatelli dddac15b52 MON:
- update x conf maxAge da appsetting.json
2022-07-15 17:23:58 +02:00
Samuele Locatelli a315e4f0ef Merge tag 'FixDisplayMonHours' into develop
Update x display ore in MON
2022-07-15 17:16:43 +02:00
Samuele Locatelli d71e9465e5 Merge branch 'release/FixDisplayMonHours' 2022-07-15 17:15:57 +02:00
Samuele Locatelli 876197b0ac Update display MON x vedere HH 2022-07-15 17:14:44 +02:00
Samuele Locatelli cd07a940d0 Merge tag 'UpdateLand4WCS' into develop
update x compatibilità con nuovi metodi WebConfigSetter
2022-07-14 17:55:44 +02:00
Samuele Locatelli d2f7dd53f3 Merge branch 'release/UpdateLand4WCS' 2022-07-14 17:55:28 +02:00
Samuele Locatelli 8c75556240 Update LAND:
- spostamento aree conf server in apposito blocco
- implementaizone compatibile con WebConfigSetter
2022-07-14 17:54:59 +02:00
Samuele Locatelli a025057865 Merge tag 'FixRedisNugetStat' into develop
Cambio modalità auto-reconnect e tentativi
2022-07-13 09:49:43 +02:00
Samuele Locatelli c5ebcd5b40 Merge branch 'release/FixRedisNugetStat' 2022-07-13 09:49:33 +02:00
Samuele Locatelli df1526d522 MP MON:
- cambio gestione auto-reconnect: più tentativi, per 10 minuti
2022-07-13 09:49:16 +02:00
Samuele Locatelli fb88e6e30d Merge tag 'FixRedisNugetStats' into develop
Fix nuget stats
2022-07-13 09:06:08 +02:00
Samuele Locatelli e83945488d Merge branch 'release/FixRedisNugetStats' 2022-07-13 09:05:53 +02:00
Samuele Locatelli 23835d330d Fix nuget redis x STATS 2022-07-13 09:05:36 +02:00
Samuele Locatelli b57885576e Merge tag 'FixRedisRegression' into develop
Update x fix regressione valore redis mal testato
2022-07-13 08:58:13 +02:00
Samuele Locatelli 417ea1a77d Merge branch 'release/FixRedisRegression' 2022-07-13 08:57:59 +02:00
Samuele Locatelli 335fdf78f0 Correzione regressione test valori redis 2022-07-13 08:57:33 +02:00
Samuele Locatelli d50e5a6860 Merge tag 'UpdatePack' into develop
Update nuget e eliminazione warnings
2022-07-13 08:29:21 +02:00
Samuele Locatelli 86d28f1901 Merge branch 'release/UpdatePack' 2022-07-13 08:28:57 +02:00
Samuele Locatelli 202c5f6faf Refresh pacchetti nuget + minor fix 2022-07-13 08:28:38 +02:00
Samuele Locatelli e2947d1017 Merge tag 'UpdateSlowTimerElapse' into develop
Aggiornamento slow time elapse (+/- 10%)
2022-07-13 07:57:33 +02:00
Samuele Locatelli 55faefcb9a Merge branch 'release/UpdateSlowTimerElapse' 2022-07-13 07:57:19 +02:00
Samuele Locatelli 1e5f894fd9 MON:
- attesa refresh variabile x client
- esclusione compilazione WASM (NON pronta)
2022-07-13 07:55:12 +02:00
Samuele Locatelli cf8baa054f Merge tag 'MonCleanup' into develop
Update con cleanup codice ed un paio di fix dispose
2022-07-12 19:06:59 +02:00
Samuele Locatelli 871a0c8ca5 Merge branch 'release/MonCleanup' 2022-07-12 19:05:53 +02:00
Samuele Locatelli 78cb17d8fc Cleanup MP/MON 2022-07-12 19:05:30 +02:00
Samuele Locatelli 22ff799204 Merge tag 'MonWithRedisChannels' into develop
Gestioen con redis channels (da ripulire...)
2022-07-12 18:45:32 +02:00
Samuele Locatelli a26408a21c Merge branch 'release/MonWithRedisChannels' 2022-07-12 18:45:18 +02:00
Samuele Locatelli ee043f81be Update MON:
- gestione tramite REDIS CHANNEL
- refresh sincrono
2022-07-12 18:44:57 +02:00
Samuele Locatelli 97741b4973 refresh libs 2022-07-12 18:44:35 +02:00
Samuele Locatelli 544c977740 Merge tag 'UpdateMonStandard' into develop
Update comportamento monitor standard
2022-07-12 17:10:37 +02:00
3842 changed files with 132272 additions and 294 deletions
+144 -38
View File
@@ -121,19 +121,32 @@ MON:build:
script:
- dotnet build $env:APP_NAME/$env:APP_NAME.csproj
WAMON:build:
SPEC:build:
stage: build
tags:
- win
variables:
PROJ_PATH: MP.WASM.Mon\Server
APP_NAME: MP.WASM.Mon.Server
SOL_NAME: MP-WAMON
APP_NAME: MP.SPEC
SOL_NAME: MP-SPEC
before_script:
- *nuget-fix
- dotnet restore "$env:SOL_NAME.sln"
script:
- dotnet build $env:PROJ_PATH/$env:APP_NAME.csproj
- dotnet build $env:APP_NAME/$env:APP_NAME.csproj
# WAMON:build:
# stage: build
# tags:
# - win
# variables:
# PROJ_PATH: MP.WASM.Mon\Server
# APP_NAME: MP.WASM.Mon.Server
# SOL_NAME: MP-WAMON
# before_script:
# - *nuget-fix
# - dotnet restore "$env:SOL_NAME.sln"
# script:
# - dotnet build $env:PROJ_PATH/$env:APP_NAME.csproj
LAND:test:
stage: test
@@ -199,22 +212,38 @@ MON:test:
script:
- dotnet test $env:APP_NAME/$env:APP_NAME.csproj
WAMON:test:
# WAMON:test:
# stage: test
# tags:
# - win
# variables:
# PROJ_PATH: MP.WASM.Mon\Server
# APP_NAME: MP.WASM.Mon.Server
# SOL_NAME: MP-WAMON
# before_script:
# - *nuget-fix
# - dotnet restore "$env:SOL_NAME.sln"
# only:
# - develop
# needs: ["WAMON:build"]
# script:
# - dotnet test $env:PROJ_PATH/$env:APP_NAME.csproj
SPEC:test:
stage: test
tags:
- win
variables:
PROJ_PATH: MP.WASM.Mon\Server
APP_NAME: MP.WASM.Mon.Server
SOL_NAME: MP-WAMON
APP_NAME: MP.SPEC
SOL_NAME: MP-SPEC
before_script:
- *nuget-fix
- dotnet restore "$env:SOL_NAME.sln"
only:
- develop
needs: ["WAMON:build"]
needs: ["SPEC:build"]
script:
- dotnet test $env:PROJ_PATH/$env:APP_NAME.csproj
- dotnet test $env:APP_NAME/$env:APP_NAME.csproj
LAND:IIS01:deploy:
stage: deploy
@@ -280,22 +309,38 @@ MON:IIS01:deploy:
script:
- dotnet publish -p:PublishProfile=IIS01.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=viadante16 -p:AllowUntrustedCertificate=true $env:APP_NAME/$env:APP_NAME.csproj
WAMON:IIS01:deploy:
# WAMON:IIS01:deploy:
# stage: deploy
# tags:
# - win
# variables:
# PROJ_PATH: MP.WASM.Mon\Server
# APP_NAME: MP.WASM.Mon.Server
# SOL_NAME: MP-WAMON
# before_script:
# - *nuget-fix
# - dotnet restore "$env:SOL_NAME.sln"
# only:
# - develop
# needs: ["WAMON:test"]
# script:
# - dotnet publish -p:PublishProfile=IIS01.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=viadante16 -p:AllowUntrustedCertificate=true $env:PROJ_PATH/$env:APP_NAME.csproj
SPEC:IIS01:deploy:
stage: deploy
tags:
- win
variables:
PROJ_PATH: MP.WASM.Mon\Server
APP_NAME: MP.WASM.Mon.Server
SOL_NAME: MP-WAMON
APP_NAME: MP.SPEC
SOL_NAME: MP-SPEC
before_script:
- *nuget-fix
- dotnet restore "$env:SOL_NAME.sln"
only:
- develop
needs: ["WAMON:test"]
needs: ["SPEC:test"]
script:
- dotnet publish -p:PublishProfile=IIS01.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=viadante16 -p:AllowUntrustedCertificate=true $env:PROJ_PATH/$env:APP_NAME.csproj
- dotnet publish -p:PublishProfile=IIS01.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=viadante16 -p:AllowUntrustedCertificate=true $env:APP_NAME/$env:APP_NAME.csproj
LAND:IIS02:deploy:
stage: deploy
@@ -365,23 +410,40 @@ MON:IIS02:deploy:
- dotnet publish -p:PublishProfile=IIS02.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=viadante16 -p:AllowUntrustedCertificate=true $env:APP_NAME/$env:APP_NAME.csproj
- dotnet publish -p:PublishProfile=IIS03.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=viadante16 -p:AllowUntrustedCertificate=true $env:APP_NAME/$env:APP_NAME.csproj
WAMON:IIS02:deploy:
# WAMON:IIS02:deploy:
# stage: deploy
# tags:
# - win
# variables:
# PROJ_PATH: MP.WASM.Mon\Server
# APP_NAME: MP.WASM.Mon.Server
# SOL_NAME: MP-WAMON
# before_script:
# - *nuget-fix
# - dotnet restore "$env:SOL_NAME.sln"
# only:
# - master
# needs: ["WAMON:build"]
# script:
# - dotnet publish -p:PublishProfile=IIS02.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=viadante16 -p:AllowUntrustedCertificate=true $env:PROJ_PATH/$env:APP_NAME.csproj
# - dotnet publish -p:PublishProfile=IIS03.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=viadante16 -p:AllowUntrustedCertificate=true $env:PROJ_PATH/$env:APP_NAME.csproj
SPEC:IIS02:deploy:
stage: deploy
tags:
- win
variables:
PROJ_PATH: MP.WASM.Mon\Server
APP_NAME: MP.WASM.Mon.Server
SOL_NAME: MP-WAMON
APP_NAME: MP.SPEC
SOL_NAME: MP-SPEC
before_script:
- *nuget-fix
- dotnet restore "$env:SOL_NAME.sln"
only:
- master
needs: ["WAMON:build"]
needs: ["SPEC:build"]
script:
- dotnet publish -p:PublishProfile=IIS02.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=viadante16 -p:AllowUntrustedCertificate=true $env:PROJ_PATH/$env:APP_NAME.csproj
- dotnet publish -p:PublishProfile=IIS03.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=viadante16 -p:AllowUntrustedCertificate=true $env:PROJ_PATH/$env:APP_NAME.csproj
- dotnet publish -p:PublishProfile=IIS02.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=viadante16 -p:AllowUntrustedCertificate=true $env:APP_NAME/$env:APP_NAME.csproj
- dotnet publish -p:PublishProfile=IIS03.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=viadante16 -p:AllowUntrustedCertificate=true $env:APP_NAME/$env:APP_NAME.csproj
LAND:installer:
stage: installer
@@ -467,24 +529,45 @@ MON:installer:
- *hashBuild
- *nexusUpload
WAMON:installer:
# WAMON:installer:
# stage: installer
# tags:
# - win
# variables:
# PROJ_PATH: MP.WASM.Mon\Server
# APP_NAME: MP.WASM.Mon.Server
# SOL_NAME: MP-WAMON
# NEXUS_PATH: MP-WAMON
# before_script:
# - *nuget-fix
# - dotnet restore "$env:SOL_NAME.sln"
# only:
# - develop
# - master
# needs: ["WAMON:build"]
# script:
# - dotnet publish -p:PublishProfile=IISProfile.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release $env:PROJ_PATH/$env:APP_NAME.csproj -o:publish
# # qui il deploy su nexus...
# - *hashBuild
# - *nexusUpload
SPEC:installer:
stage: installer
tags:
- win
variables:
PROJ_PATH: MP.WASM.Mon\Server
APP_NAME: MP.WASM.Mon.Server
SOL_NAME: MP-WAMON
NEXUS_PATH: MP-WAMON
APP_NAME: MP.SPEC
SOL_NAME: MP-SPEC
NEXUS_PATH: MP-SPEC
before_script:
- *nuget-fix
- dotnet restore "$env:SOL_NAME.sln"
only:
- develop
- master
needs: ["WAMON:build"]
needs: ["SPEC:build"]
script:
- dotnet publish -p:PublishProfile=IISProfile.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release $env:PROJ_PATH/$env:APP_NAME.csproj -o:publish
- dotnet publish -p:PublishProfile=IISProfile.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release $env:APP_NAME/$env:APP_NAME.csproj -o:publish
# qui il deploy su nexus...
- *hashBuild
- *nexusUpload
@@ -583,15 +666,37 @@ MON:release:
script:
- dotnet publish -c Release -o ./publish $env:APP_NAME/$env:APP_NAME.csproj
WAMON:release:
# WAMON:release:
# stage: release
# tags:
# - win
# variables:
# PROJ_PATH: MP.WASM.Mon\Server
# APP_NAME: MP.WASM.Mon.Server
# SOL_NAME: MP-WAMON
# NEXUS_PATH: MP-WAMON
# before_script:
# - *nuget-fix
# - dotnet restore "$env:SOL_NAME.sln"
# only:
# - tags
# except:
# - branches
# needs: ["WAMON:build"]
# artifacts:
# paths:
# - publish/
# script:
# - dotnet publish -c Release -o ./publish $env:PROJ_PATH/$env:APP_NAME.csproj
SPEC:release:
stage: release
tags:
- win
variables:
PROJ_PATH: MP.WASM.Mon\Server
APP_NAME: MP.WASM.Mon.Server
SOL_NAME: MP-WAMON
NEXUS_PATH: MP-WAMON
APP_NAME: MP.SPEC
SOL_NAME: MP-SPEC
NEXUS_PATH: MP-SPEC
before_script:
- *nuget-fix
- dotnet restore "$env:SOL_NAME.sln"
@@ -599,9 +704,10 @@ WAMON:release:
- tags
except:
- branches
needs: ["WAMON:build"]
needs: ["SPEC:build"]
artifacts:
paths:
- publish/
script:
- dotnet publish -c Release -o ./publish $env:PROJ_PATH/$env:APP_NAME.csproj
- dotnet publish -c Release -o ./publish $env:APP_NAME/$env:APP_NAME.csproj
+31
View File
@@ -0,0 +1,31 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.32126.317
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MP.Data", "MP.Data\MP.Data.csproj", "{10BA8450-301D-49C7-8E1E-21B7469C225C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MP.SPEC", "MP.SPEC\MP.SPEC.csproj", "{C777A098-6F91-45AF-A85E-0AD08CBCAC52}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{10BA8450-301D-49C7-8E1E-21B7469C225C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{10BA8450-301D-49C7-8E1E-21B7469C225C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{10BA8450-301D-49C7-8E1E-21B7469C225C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{10BA8450-301D-49C7-8E1E-21B7469C225C}.Release|Any CPU.Build.0 = Release|Any CPU
{C777A098-6F91-45AF-A85E-0AD08CBCAC52}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C777A098-6F91-45AF-A85E-0AD08CBCAC52}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C777A098-6F91-45AF-A85E-0AD08CBCAC52}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C777A098-6F91-45AF-A85E-0AD08CBCAC52}.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
+3 -2
View File
@@ -14,7 +14,8 @@ namespace MP.Data
// REDIS KEY Dati correnti
public static readonly string CONF_MON_KEY = $"{BASE_HASH}:Conf:MonDispData";
public static readonly string ACT_FLUX_DATA_KEY = $"{BASE_HASH}:Current:FluxData";
public static readonly string ACT_MSE_DATA_KEY = $"{BASE_HASH}:Current:MSE";
public static readonly string ACT_BLINK_KEY = $"{BASE_HASH}:Current:Blink";
}
}
+29 -29
View File
@@ -10,14 +10,6 @@ namespace MP.Data.Controllers
{
public class MpMonController : IDisposable
{
#region Private Fields
private static IConfiguration _configuration;
private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
#endregion Private Fields
#region Public Constructors
public MpMonController(IConfiguration configuration)
@@ -36,13 +28,13 @@ namespace MP.Data.Controllers
/// <param name="numRecord"></param>
/// <param name="searchVal"></param>
/// <returns></returns>
public List<DatabaseModels.AnagArticoli> ArticoliGetSearch(int numRecord, string searchVal = "")
public List<DatabaseModels.StatsAnagArticoli> ArticoliGetSearch(int numRecord, string searchVal = "")
{
List<DatabaseModels.AnagArticoli> dbResult = new List<DatabaseModels.AnagArticoli>();
List<DatabaseModels.StatsAnagArticoli> dbResult = new List<DatabaseModels.StatsAnagArticoli>();
using (var dbCtx = new MoonProContext(_configuration))
{
dbResult = dbCtx
.DbSetArticoli
.DbSetStatArticoli
.AsNoTracking()
.Where(x => x.CodArticolo.Contains(searchVal) || x.DescArticolo.Contains(searchVal) || x.Disegno.Contains(searchVal) || string.IsNullOrEmpty(searchVal))
.OrderBy(x => x.CodArticolo)
@@ -52,6 +44,24 @@ namespace MP.Data.Controllers
return dbResult;
}
/// <summary>
/// Elenco da tabella Macchine
/// </summary>
/// <returns></returns>
public List<DatabaseModels.ConfigModel> ConfigGetAll()
{
List<DatabaseModels.ConfigModel> dbResult = new List<DatabaseModels.ConfigModel>();
using (var dbCtx = new MoonProContext(_configuration))
{
dbResult = dbCtx
.DbSetConfig
.AsNoTracking()
.OrderBy(x => x.Chiave)
.ToList();
}
return dbResult;
}
public void Dispose()
{
}
@@ -74,24 +84,6 @@ namespace MP.Data.Controllers
return dbResult;
}
/// <summary>
/// Elenco da tabella Macchine
/// </summary>
/// <returns></returns>
public List<DatabaseModels.ConfigModel> ConfigGetAll()
{
List<DatabaseModels.ConfigModel> dbResult = new List<DatabaseModels.ConfigModel>();
using (var dbCtx = new MoonProContext(_configuration))
{
dbResult = dbCtx
.DbSetConfig
.AsNoTracking()
.OrderBy(x => x.Chiave)
.ToList();
}
return dbResult;
}
/// <summary>
/// Elenco da tabella MappaStatoExpl
/// </summary>
@@ -138,5 +130,13 @@ namespace MP.Data.Controllers
}
#endregion Public Methods
#region Private Fields
private static IConfiguration _configuration;
private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
#endregion Private Fields
}
}
+618
View File
@@ -0,0 +1,618 @@
using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using NLog;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace MP.Data.Controllers
{
public class MpSpecController : IDisposable
{
#region Public Constructors
public MpSpecController(IConfiguration configuration)
{
_configuration = configuration;
Log.Info("Avviata classe MpSpecController");
}
#endregion Public Constructors
#region Public Methods
/// <summary>
/// Elenco Gruppi tipo Azienda
/// </summary>
/// <returns></returns>
public List<DatabaseModels.AnagGruppi> AnagGruppiAziende()
{
return AnagGruppiGetTipo("AZIENDA");
}
/// <summary>
/// Elenco Gruppi tipo Fasi
/// </summary>
/// <returns></returns>
public List<DatabaseModels.AnagGruppi> AnagGruppiFase()
{
return AnagGruppiGetTipo("FASE");
}
/// <summary>
/// Elenco Gruppi
/// </summary>
/// <returns></returns>
public List<DatabaseModels.AnagGruppi> AnagGruppiGetAll()
{
List<DatabaseModels.AnagGruppi> dbResult = new List<DatabaseModels.AnagGruppi>();
using (var dbCtx = new MoonProContext(_configuration))
{
dbResult = dbCtx
.DbSetAnagGruppi
.AsNoTracking()
.OrderBy(x => x.CodGruppo)
.ToList();
}
return dbResult;
}
/// <summary>
/// Gruppi x tipo
/// </summary>
/// <param name="tipoGruppo"></param>
/// <returns></returns>
public List<DatabaseModels.AnagGruppi> AnagGruppiGetTipo(string tipoGruppo)
{
List<DatabaseModels.AnagGruppi> dbResult = new List<DatabaseModels.AnagGruppi>();
using (var dbCtx = new MoonProContext(_configuration))
{
dbResult = dbCtx
.DbSetAnagGruppi
.Where(x => x.TipoGruppo == tipoGruppo)
.AsNoTracking()
.OrderBy(x => x.CodGruppo)
.ToList();
}
return dbResult;
}
/// <summary>
/// Elenco valori ammessi x Stati commessa (es Yacht Baglietto)
/// </summary>
/// <returns></returns>
public List<DatabaseModels.ListValues> AnagStatiComm()
{
return ListValuesFilt("PODL", "StatoComm");
}
/// <summary>
/// Elenco valori ammessi x Tipo articoli
/// </summary>
/// <returns></returns>
public List<DatabaseModels.ListValues> AnagTipoArtLV()
{
return ListValuesFilt("AnagArticoli", "Tipo");
}
/// <summary>
/// Eliminazione Record
/// </summary>
/// <param name="currRec"></param>
/// <returns></returns>
public async Task<bool> ArticoliDeleteRecord(DatabaseModels.AnagArticoli currRec)
{
bool fatto = false;
using (var dbCtx = new MoonProContext(_configuration))
{
try
{
var currVal = dbCtx
.DbSetArticoli
.Where(x => x.CodArticolo == currRec.CodArticolo)
.FirstOrDefault();
dbCtx
.DbSetArticoli
.Remove(currVal);
await dbCtx.SaveChangesAsync();
fatto = true;
}
catch (Exception exc)
{
Log.Error($"Eccezione durante ArticoliDeleteRecord{Environment.NewLine}{exc}");
}
}
return fatto;
}
/// <summary>
/// Elenco tabella Articoli da filtro
/// </summary>
/// <param name="numRecord"></param>
/// <param name="searchVal"></param>
/// <returns></returns>
public List<DatabaseModels.AnagArticoli> ArticoliGetSearch(int numRecord, string searchVal = "")
{
List<DatabaseModels.AnagArticoli> dbResult = new List<DatabaseModels.AnagArticoli>();
using (var dbCtx = new MoonProContext(_configuration))
{
dbResult = dbCtx
.DbSetArticoli
.AsNoTracking()
.Where(x => x.CodArticolo.Contains(searchVal) || x.DescArticolo.Contains(searchVal) || x.Disegno.Contains(searchVal) || string.IsNullOrEmpty(searchVal))
.OrderBy(x => x.CodArticolo)
.Take(numRecord)
.ToList();
}
return dbResult;
}
/// <summary>
/// Elenco tabella Articoli da filtro
/// </summary>
/// <param name="numRecord"></param>
/// <param name="azienda"></param>
/// <param name="searchVal"></param>
/// <returns></returns>
public List<DatabaseModels.AnagArticoli> ArticoliGetSearch(int numRecord, string azienda = "*", string searchVal = "")
{
List<DatabaseModels.AnagArticoli> dbResult = new List<DatabaseModels.AnagArticoli>();
using (var dbCtx = new MoonProContext(_configuration))
{
dbResult = dbCtx
.DbSetArticoli
.AsNoTracking()
.Where(x => (x.Azienda == azienda || azienda == "*") && (x.CodArticolo.Contains(searchVal) || x.DescArticolo.Contains(searchVal) || x.Disegno.Contains(searchVal) || string.IsNullOrEmpty(searchVal)))
.OrderBy(x => x.CodArticolo)
.Take(numRecord)
.ToList();
}
return dbResult;
}
/// <summary>
/// Elenco tabella Articoli IMPIEGATI (da stored stp_ART_getUsed)
/// </summary>
/// <returns></returns>
public List<DatabaseModels.AnagArticoli> ArticoliGetUsed()
{
List<DatabaseModels.AnagArticoli> dbResult = new List<DatabaseModels.AnagArticoli>();
using (var dbCtx = new MoonProContext(_configuration))
{
dbResult = dbCtx
.DbSetArticoli
.FromSqlRaw("EXEC stp_ART_getUsed")
.AsNoTracking()
.ToList();
}
return dbResult;
}
/// <summary>
/// Update Record
/// </summary>
/// <param name="currRec"></param>
/// <returns></returns>
public async Task<bool> ArticoliUpdateRecord(DatabaseModels.AnagArticoli editRec)
{
bool fatto = false;
using (var dbCtx = new MoonProContext(_configuration))
{
try
{
var currRec = dbCtx
.DbSetArticoli
.Where(x => x.CodArticolo == editRec.CodArticolo)
.FirstOrDefault();
if (currRec != null)
{
currRec.Disegno = editRec.Disegno;
currRec.DescArticolo = editRec.DescArticolo;
currRec.Tipo = editRec.Tipo;
currRec.Azienda = editRec.Azienda;
dbCtx.Entry(currRec).State = EntityState.Modified;
}
else
{
dbCtx
.DbSetArticoli
.Add(editRec);
}
await dbCtx.SaveChangesAsync();
fatto = true;
}
catch (Exception exc)
{
Log.Error($"Eccezione durante ArticoliUpdateRecord{Environment.NewLine}{exc}");
}
}
return fatto;
}
/// <summary>
/// Elenco da tabella Config
/// </summary>
/// <returns></returns>
public List<DatabaseModels.ConfigModel> ConfigGetAll()
{
List<DatabaseModels.ConfigModel> dbResult = new List<DatabaseModels.ConfigModel>();
using (var dbCtx = new MoonProContext(_configuration))
{
dbResult = dbCtx
.DbSetConfig
.AsNoTracking()
.OrderBy(x => x.Chiave)
.ToList();
}
return dbResult;
}
/// <summary>
/// Update record config
/// </summary>
/// <returns></returns>
public bool ConfigUpdate(DatabaseModels.ConfigModel updRec)
{
bool fatto = false;
DatabaseModels.ConfigModel dbResult = new DatabaseModels.ConfigModel();
using (var dbCtx = new MoonProContext(_configuration))
{
dbResult = dbCtx
.DbSetConfig
.Where(x => x.Chiave == updRec.Chiave)
.FirstOrDefault();
if (dbResult != null)
{
dbResult.Valore = updRec.Valore;
dbCtx.SaveChanges();
fatto = true;
}
}
return fatto;
}
public void Dispose()
{
}
/// <summary>
/// Elenco ultimi n record DOssiers (che contengono ad esempio "salvataggi" di FLuxLog) dato
/// macchina (ordinato x data registrazione)
/// </summary>
/// <param name="IdxMacchina">* = tutte, altrimenti solo x una data macchina</param>
/// <param name="DtRef">Data di riferimento (Massima) per estrazioen records</param>
/// <param name="MaxRec">numero massimo record da restituire</param>
/// <returns></returns>
public List<DatabaseModels.Dossiers> DossiersGetLastFilt(string IdxMacchina, DateTime DtRef, int MaxRec)
{
List<DatabaseModels.Dossiers> dbResult = new List<DatabaseModels.Dossiers>();
using (var dbCtx = new MoonProContext(_configuration))
{
dbResult = dbCtx
.DbSetDossiers
.AsNoTracking()
.Where(x => (IdxMacchina == "*" || x.IdxMacchina == IdxMacchina) && x.DtRif <= DtRef)
.OrderByDescending(x => x.DtRif)
.Take(MaxRec)
.ToList();
}
return dbResult;
}
public bool DossiersTakeParamsSnapshot(string idxMacchina, int maxSec)
{
bool answ = false;
using (var dbCtx = new MoonProContext(_configuration))
{
var pIdxMacchina = new SqlParameter("@IdxMacchina", idxMacchina);
var pMaxSec = new SqlParameter("@MaxSec", maxSec);
var dbResult = dbCtx
.Database
.ExecuteSqlRaw("EXEC stp_FL_TakeSnapshot @IdxMacchina,@MaxSec", pIdxMacchina, pMaxSec);
answ = true;
}
return answ;
}
/// <summary>
/// Elenco valori link (x home e navMenu laterale)
/// </summary>
/// <returns></returns>
public List<DatabaseModels.LinkMenu> ElencoLink()
{
return ListLinkFilt("SpecLink");
}
/// <summary>
/// Elenco ultimi n record flux log dato macchina e flusso (ordinato x data registrazione)
/// </summary>
/// <param name="IdxMacchina">* = tutte, altrimenti solo x una data macchina</param>
/// <param name="CodFlux">*=tutti, altrimenti solo selezionato</param>
/// <param name="MaxRec">numero massimo record da restituire</param>
/// <returns></returns>
public List<DatabaseModels.FluxLog> FluxLogGetLastFilt(string IdxMacchina, string CodFlux, int MaxRec)
{
List<DatabaseModels.FluxLog> dbResult = new List<DatabaseModels.FluxLog>();
using (var dbCtx = new MoonProContext(_configuration))
{
dbResult = dbCtx
.DbSetFluxLog
.AsNoTracking()
.Where(x => (IdxMacchina == "*" || x.IdxMacchina == IdxMacchina) && (CodFlux == "*" || x.CodFlux == CodFlux))
.OrderByDescending(x => x.dtEvento)
.Take(MaxRec)
.ToList();
}
return dbResult;
}
public List<DatabaseModels.LinkMenu> ListLinkFilt(string tipoLink)
{
List<DatabaseModels.LinkMenu> dbResult = new List<DatabaseModels.LinkMenu>();
using (var dbCtx = new MoonProContext(_configuration))
{
dbResult = dbCtx
.DbSetLinkMenu
.Where(x => x.TipoLink == tipoLink)
.AsNoTracking()
.OrderBy(x => x.ordine)
.ToList();
}
return dbResult;
}
/// <summary>
/// Elenco ODL filtrati x stato, articolo, KeyRich (che contiene stato)
/// </summary>
/// <param name="inCorso">Stato ODL: true=in corso/completato</param>
/// <param name="codArt">Cod articolo</param>
/// <param name="keyRichPart">KeyRich (parziale) da cercare (es cod stato x yacht)</param>
/// <returns></returns>
public List<DatabaseModels.ODLModel> ListODLFilt(bool inCorso, string codArt, string keyRichPart)
{
List<DatabaseModels.ODLModel> dbResult = new List<DatabaseModels.ODLModel>();
using (var dbCtx = new MoonProContext(_configuration))
{
dbResult = dbCtx
.DbSetODL
.Where(x => ((inCorso && x.DataFine == null) || (!inCorso && x.DataFine != null)) && (x.KeyRichiesta.Contains(keyRichPart) || keyRichPart == "*") && (codArt == "*" || x.CodArticolo.Contains(codArt)))
.AsNoTracking()
.OrderBy(x => x.IdxOdl)
.ToList();
}
return dbResult;
}
/// <summary>
/// Elenco PODL non avviati filtrati x articolo, KeyRich (che contiene stato)
/// </summary>
/// <param name="codArt">Cod articolo</param>
/// <param name="keyRichPart">KeyRich (parziale) da cercare (es cod stato x yacht)</param>
/// <returns></returns>
public List<DatabaseModels.PODLModel> ListPODLFilt(string codArt, string keyRichPart)
{
List<DatabaseModels.PODLModel> dbResult = new List<DatabaseModels.PODLModel>();
using (var dbCtx = new MoonProContext(_configuration))
{
dbResult = dbCtx
.DbSetPODL
.Where(x => (x.IdxOdl == 0) && (x.KeyRichiesta.Contains(keyRichPart) || keyRichPart == "*") && (codArt == "*" || x.CodArticolo.Contains(codArt)))
.AsNoTracking()
.OrderBy(x => x.InsertDate)
.ToList();
}
return dbResult;
}
/// <summary>
/// Elenco valori ammessi x tabella/colonna
/// </summary>
/// <param name="tabName"></param>
/// <param name="fieldName"></param>
/// <returns></returns>
public List<DatabaseModels.ListValues> ListValuesFilt(string tabName, string fieldName)
{
List<DatabaseModels.ListValues> dbResult = new List<DatabaseModels.ListValues>();
using (var dbCtx = new MoonProContext(_configuration))
{
dbResult = dbCtx
.DbSetListValues
.Where(x => x.TableName == tabName && x.FieldName == fieldName)
.AsNoTracking()
.OrderBy(x => x.ordinal)
.ToList();
}
return dbResult;
}
/// <summary>
/// Elenco da tabella Macchine
/// </summary>
/// <returns></returns>
public List<DatabaseModels.Macchine> MacchineGetAll()
{
List<DatabaseModels.Macchine> dbResult = new List<DatabaseModels.Macchine>();
using (var dbCtx = new MoonProContext(_configuration))
{
dbResult = dbCtx
.DbSetMacchine
.AsNoTracking()
.OrderBy(x => x.IdxMacchina)
.ToList();
}
return dbResult;
}
/// <summary>
/// Elenco id Macchine che abbiano dati FLuxLog
/// </summary>
/// <returns></returns>
public List<string> MacchineWithFlux()
{
List<string> dbResult = new List<string>();
using (var dbCtx = new MoonProContext(_configuration))
{
dbResult = dbCtx
.DbSetFluxLog
.AsNoTracking()
.Select(i => i.IdxMacchina)
.Distinct()
.ToList();
}
return dbResult;
}
/// <summary>
/// Elenco da tabella MappaStatoExpl
/// </summary>
/// <returns></returns>
public List<DatabaseModels.MappaStatoExpl> MseGetAll(int maxAge = 2000)
{
List<DatabaseModels.MappaStatoExpl> dbResult = new List<DatabaseModels.MappaStatoExpl>();
using (var dbCtx = new MoonProContext(_configuration))
{
var maxAgeSec = new SqlParameter("@maxAgeSec", maxAge);
dbResult = dbCtx
.DbSetMSE
.FromSqlRaw("EXEC stp_MSE_getData @maxAgeSec", maxAgeSec)
.AsNoTracking()
.ToList();
}
return dbResult;
}
/// <summary>
/// Elenco parametri validi x una data macchina
/// </summary>
/// <param name="IdxMacchina"></param>
/// <returns></returns>
public List<string> ParametriGetFilt(string IdxMacchina)
{
List<string> dbResult = new List<string>();
using (var dbCtx = new MoonProContext(_configuration))
{
dbResult = dbCtx
.DbSetFluxLog
.AsNoTracking()
.Where(x => (IdxMacchina == "*" || x.IdxMacchina == IdxMacchina))
.Select(i => i.CodFlux)
.Distinct()
.ToList();
}
return dbResult;
}
/// <summary>
/// Eliminazione Record
/// </summary>
/// <param name="currRec"></param>
/// <returns></returns>
public async Task<bool> PODLDeleteRecord(DatabaseModels.PODLModel currRec)
{
bool fatto = false;
using (var dbCtx = new MoonProContext(_configuration))
{
try
{
var currVal = dbCtx
.DbSetPODL
.Where(x => x.IdxPromessa == currRec.IdxPromessa)
.FirstOrDefault();
dbCtx
.DbSetPODL
.Remove(currVal);
await dbCtx.SaveChangesAsync();
fatto = true;
}
catch (Exception exc)
{
Log.Error($"Eccezione durante PODLDeleteRecord{Environment.NewLine}{exc}");
}
}
return fatto;
}
/// <summary>
/// Update Record
/// </summary>
/// <param name="currRec"></param>
/// <returns></returns>
public async Task<bool> PODLUpdateRecord(DatabaseModels.PODLModel editRec)
{
bool fatto = false;
using (var dbCtx = new MoonProContext(_configuration))
{
try
{
var currRec = dbCtx
.DbSetPODL
.Where(x => x.IdxPromessa == editRec.IdxPromessa)
.FirstOrDefault();
if (currRec != null)
{
currRec.CodGruppo = editRec.CodGruppo;
currRec.CodArticolo = editRec.CodArticolo;
currRec.IdxMacchina = editRec.IdxMacchina;
currRec.KeyBCode = editRec.KeyBCode;
currRec.KeyRichiesta = editRec.KeyRichiesta;
currRec.NumPezzi = editRec.NumPezzi;
currRec.Tcassegnato = editRec.Tcassegnato;
dbCtx.Entry(currRec).State = EntityState.Modified;
}
else
{
dbCtx
.DbSetPODL
.Add(editRec);
}
await dbCtx.SaveChangesAsync();
fatto = true;
}
catch (Exception exc)
{
Log.Error($"Eccezione durante PODLUpdateRecord{Environment.NewLine}{exc}");
}
}
return fatto;
}
/// <summary>
/// Annulla modifiche su una specifica entity (cancel update)
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
public bool RollBackEntity(object item)
{
bool answ = false;
using (var dbCtx = new MoonProContext(_configuration))
{
try
{
if (dbCtx.Entry(item).State == Microsoft.EntityFrameworkCore.EntityState.Deleted || dbCtx.Entry(item).State == Microsoft.EntityFrameworkCore.EntityState.Modified)
{
dbCtx.Entry(item).Reload();
}
}
catch (Exception exc)
{
Log.Error($"Eccezione in rollBackEntity{Environment.NewLine}{exc}");
}
}
return answ;
}
#endregion Public Methods
#region Private Fields
private static IConfiguration _configuration;
private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
#endregion Private Fields
}
}
+6 -6
View File
@@ -52,9 +52,9 @@ namespace MP.Data.Controllers
/// <param name="numRecord"></param>
/// <param name="searchVal"></param>
/// <returns></returns>
public List<DatabaseModels.AnagArticoli> ArticoliGetSearch(int numRecord, string searchVal = "")
public List<DatabaseModels.StatsAnagArticoli> ArticoliGetSearch(int numRecord, string searchVal = "")
{
List<DatabaseModels.AnagArticoli> dbResult = new List<DatabaseModels.AnagArticoli>();
List<DatabaseModels.StatsAnagArticoli> dbResult = new List<DatabaseModels.StatsAnagArticoli>();
using (var dbCtx = new MoonPro_STATSContext(_configuration))
{
dbResult = dbCtx
@@ -73,9 +73,9 @@ namespace MP.Data.Controllers
/// <param name="numRecord"></param>
/// <param name="searchVal"></param>
/// <returns></returns>
public List<DatabaseModels.ODL> CommesseGetSearch(int numRecord, string searchVal = "")
public List<DatabaseModels.StatsODL> CommesseGetSearch(int numRecord, string searchVal = "")
{
List<DatabaseModels.ODL> dbResult = new List<DatabaseModels.ODL>();
List<DatabaseModels.StatsODL> dbResult = new List<DatabaseModels.StatsODL>();
using (var dbCtx = new MoonPro_STATSContext(_configuration))
{
dbResult = dbCtx
@@ -223,9 +223,9 @@ namespace MP.Data.Controllers
/// <param name="numRecord"></param>
/// <param name="searchVal"></param>
/// <returns></returns>
public List<DatabaseModels.ODL> StatOdlGetAll(DateTime DataStart, DateTime DataEnd, string IdxMacchina, int IdxODL, string KeyRichiesta, string CodArticolo)
public List<DatabaseModels.StatsODL> StatOdlGetAll(DateTime DataStart, DateTime DataEnd, string IdxMacchina, int IdxODL, string KeyRichiesta, string CodArticolo)
{
List<DatabaseModels.ODL> dbResult = new List<DatabaseModels.ODL>();
List<DatabaseModels.StatsODL> dbResult = new List<DatabaseModels.StatsODL>();
using (var dbCtx = new MoonPro_STATSContext(_configuration))
{
var dataFrom = new SqlParameter("@dataFrom", DataStart);
+14
View File
@@ -0,0 +1,14 @@
using MP.Data.DatabaseModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MP.Data.DTO
{
public class DossierFluxLogDTO
{
public List<FluxLog> ODL { get; set; } = new List<FluxLog>();
}
}
+3
View File
@@ -1,10 +1,12 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
#nullable disable
namespace MP.Data.DatabaseModels
{
[Table("AnagArticoli")]
public partial class AnagArticoli
{
#region Public Properties
@@ -13,6 +15,7 @@ namespace MP.Data.DatabaseModels
public string DescArticolo { get; set; }
public string Disegno { get; set; }
public string Tipo { get; set; }
public string Azienda { get; set; }
#endregion Public Properties
}
+28
View File
@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
#nullable disable
namespace MP.Data.DatabaseModels
{
[Table("AnagraficaGruppi")]
public partial class AnagGruppi
{
#region Public Properties
//[Key, DatabaseGenerated(DatabaseGeneratedOption.None), MaxLength(50)]
public string CodGruppo { get; set; }
//[MaxLength(50)]
public string TipoGruppo { get; set; }
//[MaxLength(250)]
public string DescrGruppo { get; set; }
public bool SelEnabled { get; set; }
#endregion Public Properties
}
}
+28
View File
@@ -0,0 +1,28 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
#nullable disable
namespace MP.Data.DatabaseModels
{
[Table("Dossiers")]
public partial class Dossiers
{
#region Public Properties
[MaxLength(50)]
public string IdxMacchina { get; set; }
public DateTime DtRif { get; set; }
public int IdxODL { get; set; }
[MaxLength(50)]
public string DataType { get; set; }
public string Valore { get; set; }
#endregion Public Properties
}
}
+29
View File
@@ -0,0 +1,29 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
#nullable disable
namespace MP.Data.DatabaseModels
{
[Table("FluxLog")]
public partial class FluxLog
{
#region Public Properties
[MaxLength(50)]
public string IdxMacchina { get; set; }
public DateTime dtEvento { get; set; }
[MaxLength(50)]
public string CodFlux { get; set; }
[MaxLength(250)]
public string Valore { get; set; }
public int Cnt { get; set; }
#endregion Public Properties
}
}
+35
View File
@@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
#nullable disable
namespace MP.Data.DatabaseModels
{
[Table("LinkMenuJQM")]
public partial class LinkMenu
{
#region Public Properties
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int idxLink { get; set; }
[MaxLength(50)]
public string TipoLink { get; set; } = "";
public int ordine { get; set; } = 0;
[MaxLength(50)]
public string Testo { get; set; } = "";
[MaxLength(50)]
public string NavigateUrl { get; set; } = "";
[MaxLength(50)]
public string icona { get; set; } = "";
#endregion Public Properties
}
}
+29
View File
@@ -0,0 +1,29 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
#nullable disable
namespace MP.Data.DatabaseModels
{
[Table("ListValues")]
public partial class ListValues
{
#region Public Properties
[MaxLength(50)]
public string TableName { get; set; }
[MaxLength(50)]
public string FieldName { get; set; }
[MaxLength(50)]
public string value { get; set; }
[MaxLength(50)]
public string label { get; set; }
public int ordinal { get; set; }
#endregion Public Properties
}
}
+35
View File
@@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
#nullable disable
namespace MP.Data.DatabaseModels
{
[Table("ODL")]
public partial class ODLModel
{
#region Public Properties
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int IdxOdl { get; set; }
[MaxLength(50)]
public string CodArticolo { get; set; } = "";
[MaxLength(50)]
public string IdxMacchina { get; set; }
public int NumPezzi { get; set; }
public decimal Tcassegnato { get; set; }
public DateTime? DataInizio { get; set; }
public DateTime? DataFine { get; set; }
[MaxLength(2500)]
public string Note { get; set; } = "";
[MaxLength(50)]
public string KeyRichiesta { get; set; }
public int PzPallet { get; set; } = 1;
[MaxLength(50)]
public string CodCli { get; set; } = "";
#endregion Public Properties
}
}
+57
View File
@@ -0,0 +1,57 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
#nullable disable
namespace MP.Data.DatabaseModels
{
[Table("PromesseODL")]
public partial class PODLModel
{
#region Public Properties
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int IdxPromessa { get; set; }
[MaxLength(50)]
public string KeyRichiesta { get; set; }
[MaxLength(50)]
public string KeyBCode { get; set; }
public bool Attivabile { get; set; } = false;
public int IdxOdl { get; set; } = 0;
[MaxLength(50)]
public string CodArticolo { get; set; } = "";
[MaxLength(50)]
public string CodGruppo { get; set; } = "";
[MaxLength(50)]
public string IdxMacchina { get; set; }
public int NumPezzi { get; set; } = 1;
public decimal Tcassegnato { get; set; } = 1;
public DateTime? DueDate { get; set; }
public int Priorita { get; set; } = 1;
public int PzPallet { get; set; } = 1;
[MaxLength(2500)]
public string Note { get; set; } = "";
[MaxLength(50)]
public string CodCli { get; set; } = "";
public DateTime InsertDate { get; set; } = DateTime.Now;
[NotMapped]
public string CodFase
{
get
{
string answ = "*";
var allData = KeyRichiesta.Split('_');
if (allData.Length > 0)
{
answ = allData[0];
}
return answ;
}
}
#endregion Public Properties
}
}
@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
#nullable disable
namespace MP.Data.DatabaseModels
{
public partial class StatsAnagArticoli
{
#region Public Properties
public string CodArticolo { get; set; }
public string DescArticolo { get; set; }
public string Disegno { get; set; }
public string Tipo { get; set; }
#endregion Public Properties
}
}
@@ -5,7 +5,7 @@ using System.Collections.Generic;
namespace MP.Data.DatabaseModels
{
public partial class ODL
public partial class StatsODL
{
#region Public Properties
+6 -6
View File
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
@@ -12,14 +12,14 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.6">
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.7">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="6.0.6" />
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="6.0.7" />
<PackageReference Include="NLog" Version="5.0.1" />
</ItemGroup>
</Project>
+135
View File
@@ -0,0 +1,135 @@
using NLog;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MP.Data
{
public class MessagePipe
{
#region Private Fields
private bool enableLog = false;
private IConnectionMultiplexer redis;
private IDatabase? redisDb;
#endregion Private Fields
#region Protected Fields
protected static Logger Log = LogManager.GetCurrentClassLogger();
#endregion Protected Fields
#region Public Constructors
public MessagePipe(IConnectionMultiplexer redisConn, string channelName, bool enableLog = false)
{
_channel = channelName;
redis = redisConn;
redisDb = redis.GetDatabase();
this.enableLog = enableLog;
// aggiungo sottoscrittore
setupSubscriber();
}
#endregion Public Constructors
#region Public Events
public event EventHandler EA_NewMessage = delegate { };
#endregion Public Events
#region Private Properties
/// <summary>
/// Canale associato al gestore pipeline messaggi
/// </summary>
private string _channel { get; set; } = "";
#endregion Private Properties
#region Private Methods
private void setupSubscriber()
{
ISubscriber sub = redis.GetSubscriber();
//Subscribe to the channel named messages
sub.Subscribe(_channel, (channel, message) =>
{
Log.Trace($"ch {channel} | {message}");
// messaggio
PubSubEventArgs mea = new PubSubEventArgs(message);
// se qualcuno ascolta sollevo evento nuovo valore...
if (EA_NewMessage != null)
{
EA_NewMessage(this, mea);
}
});
Log.Info($"Subscribed {_channel}");
}
#endregion Private Methods
#region Public Methods
public bool saveAndSendMessage(string memKey, string message)
{
bool answ = false;
// invio notifica tramite il canale richiesto
answ = sendMessage(message);
if (redisDb != null)
{
redisDb.StringSetAsync(memKey, message);
if (enableLog)
{
Log.Info($"Redis Cache Key: {memKey}");
}
}
return answ;
}
/// <summary>
/// Invio messaggio sul canale
/// </summary>
/// <param name="newMess"></param>
/// <returns></returns>
public bool sendMessage(string newMess)
{
bool answ = false;
ISubscriber sub = redis.GetSubscriber();
sub.Publish(_channel, newMess);
return answ;
}
#endregion Public Methods
/// <summary>
/// Invio messaggio sul canale + salvataggio in cache REDIS
/// </summary>
/// <param name="memKey">Chiave REDIS x salvare valore</param>
/// <param name="message"></param>
}
public class PubSubEventArgs : EventArgs
{
#region Public Constructors
public PubSubEventArgs(string messaggio)
{
this.newMessage = messaggio;
}
#endregion Public Constructors
#region Public Properties
public string newMessage { get; set; } = "";
#endregion Public Properties
}
}
+81 -4
View File
@@ -34,10 +34,18 @@ namespace MP.Data
#region Public Properties
public virtual DbSet<StatsAnagArticoli> DbSetStatArticoli { get; set; }
public virtual DbSet<AnagArticoli> DbSetArticoli { get; set; }
public virtual DbSet<Macchine> DbSetMacchine { get; set; }
public virtual DbSet<MappaStatoExpl> DbSetMSE { get; set; }
public virtual DbSet<ConfigModel> DbSetConfig { get; set; }
public virtual DbSet<AnagGruppi> DbSetAnagGruppi { get; set; }
public virtual DbSet<ListValues> DbSetListValues { get; set; }
public virtual DbSet<LinkMenu> DbSetLinkMenu { get; set; }
public virtual DbSet<ODLModel> DbSetODL { get; set; }
public virtual DbSet<PODLModel> DbSetPODL { get; set; }
public virtual DbSet<FluxLog> DbSetFluxLog { get; set; }
public virtual DbSet<Dossiers> DbSetDossiers { get; set; }
#endregion Public Properties
@@ -53,7 +61,15 @@ namespace MP.Data
{
if (!optionsBuilder.IsConfigured)
{
string connString = _configuration.GetConnectionString("Mp.Mon");
string connString = _configuration.GetConnectionString("Mp.Data");
if (string.IsNullOrEmpty(connString))
{
connString = _configuration.GetConnectionString("Mp.Mon");
}
if (string.IsNullOrEmpty(connString))
{
connString = _configuration.GetConnectionString("Mp.STATS");
}
optionsBuilder.UseSqlServer(connString);
//optionsBuilder.UseSqlServer("Server=SQL2016DEV;Database=MoonPro;Trusted_Connection=True;");
@@ -64,9 +80,9 @@ namespace MP.Data
{
modelBuilder.HasAnnotation("Relational:Collation", "SQL_Latin1_General_CP1_CI_AS");
modelBuilder.Entity<AnagArticoli>(entity =>
modelBuilder.Entity<StatsAnagArticoli>(entity =>
{
entity.HasNoKey();
entity.HasKey(e => e.CodArticolo);
entity.ToView("v_UI_AnagArticoli");
@@ -86,10 +102,36 @@ namespace MP.Data
.IsRequired()
.HasMaxLength(50);
});
modelBuilder.Entity<AnagArticoli>(entity =>
{
entity.HasKey(e => e.CodArticolo);
entity.ToView("AnagArticoli");
entity.Property(e => e.CodArticolo)
.IsRequired()
.HasMaxLength(50);
entity.Property(e => e.DescArticolo)
.IsRequired()
.HasMaxLength(250);
entity.Property(e => e.Disegno)
.IsRequired()
.HasMaxLength(50);
entity.Property(e => e.Tipo)
.IsRequired()
.HasMaxLength(50);
entity.Property(e => e.Azienda)
.IsRequired()
.HasMaxLength(50);
});
modelBuilder.Entity<Macchine>(entity =>
{
entity.HasNoKey();
entity.HasKey(e => e.IdxMacchina);
entity.ToView("Macchine");
@@ -223,6 +265,41 @@ namespace MP.Data
.HasColumnName("valoreStd")
.HasComment("Valore di default/riferimento per la variabile");
});
modelBuilder.Entity<AnagGruppi>(entity =>
{
entity.HasKey(e => e.CodGruppo);
entity.Property(e => e.CodGruppo)
.HasMaxLength(50)
.HasColumnName("CodGruppo");
entity.Property(e => e.TipoGruppo)
.HasMaxLength(50)
.HasColumnName("TipoGruppo");
entity.Property(e => e.DescrGruppo)
.HasMaxLength(250)
.HasColumnName("DescrGruppo");
entity.Property(e => e.SelEnabled)
.HasColumnName("SelEnabled");
});
modelBuilder.Entity<ListValues>(entity =>
{
entity.HasKey(e => new { e.TableName, e.FieldName, e.value });
});
modelBuilder.Entity<FluxLog>(entity =>
{
entity.HasKey(e => new { e.IdxMacchina, e.dtEvento, e.CodFlux });
});
modelBuilder.Entity<Dossiers>(entity =>
{
entity.HasKey(e => new { e.IdxMacchina, e.DtRif });
});
OnModelCreatingPartial(modelBuilder);
}
+4 -4
View File
@@ -34,12 +34,12 @@ namespace MP.Data
#region Public Properties
public virtual DbSet<AnagArticoli> DbSetArticoli { get; set; }
public virtual DbSet<StatsAnagArticoli> DbSetArticoli { get; set; }
public virtual DbSet<AzioniUL> DbSetAzioniUL { get; set; }
public virtual DbSet<ResControlli> DbSetControlli { get; set; }
public virtual DbSet<DdbTurni> DbSetDdbTurni { get; set; }
public virtual DbSet<Macchine> DbSetMacchine { get; set; }
public virtual DbSet<ODL> DbSetODL { get; set; }
public virtual DbSet<StatsODL> DbSetODL { get; set; }
public virtual DbSet<ResScarti> DbSetScarti { get; set; }
public virtual DbSet<TurniOee> DbSetTurniOee { get; set; }
public virtual DbSet<UserActionLog> DbSetUserLog { get; set; }
@@ -98,7 +98,7 @@ namespace MP.Data
.HasMaxLength(5);
});
modelBuilder.Entity<AnagArticoli>(entity =>
modelBuilder.Entity<StatsAnagArticoli>(entity =>
{
entity.HasNoKey();
@@ -325,7 +325,7 @@ namespace MP.Data
.HasMaxLength(250);
});
modelBuilder.Entity<ODL>(entity =>
modelBuilder.Entity<StatsODL>(entity =>
{
entity.HasKey(e => e.IdxOdl)
.HasName("PK_ODL_1");
+24
View File
@@ -39,6 +39,30 @@ namespace MP.Data
await Task.Run(() => File.WriteAllLines(path, lines.ToArray()));
}
public static string redKeyArtUsed
{
get => RedHash($"CACHE:CheckArtUsed");
}
public static string redKeyTabCheckArt
{
get => RedHash($"CACHE:TabCheckArt");
}
/// <summary>
/// Nome della variabile HASH da utilizzare (dato CodModulo / Server / DB impiegato da funzionalita' DbConfig) + keyName richiesto...
/// </summary>
public static string RedHash(string keyName)
{
string answ = keyName;
try
{
answ =$"MP:Data:{keyName}";
}
catch
{ }
return answ;
}
#endregion Public Methods
}
}
+1 -1
View File
@@ -118,7 +118,7 @@ else // disegno box non cliccabile e licenza mancante
protected string fullUrl(string relUrl)
{
return $"{Configuration["BaseUrl"]}{relUrl}";
return $"{Configuration["ServerConf:BaseUrl"]}{relUrl}";
}
protected MarkupString traduci(string lemma)
+2 -2
View File
@@ -81,12 +81,12 @@ namespace MP.Land.Components
protected string fullUrl(string relUrl)
{
return $"{Configuration["BaseUrl"]}{relUrl}";
return $"{Configuration["ServerConf:BaseUrl"]}{relUrl}";
}
protected string localPath(string localRepo)
{
return @$"{Configuration["downloadPath"]}\{localRepo}\{Configuration["appVers"]}"; ;
return @$"{Configuration["ServerConf:downloadPath"]}\{localRepo}\{Configuration["appVers"]}"; ;
}
protected override void OnInitialized()
+1 -1
View File
@@ -3,7 +3,7 @@
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace>MP.Land</RootNamespace>
<Version>6.15.2207.0718</Version>
<Version>6.15.2209.1212</Version>
</PropertyGroup>
<ItemGroup>
+1 -1
View File
@@ -121,7 +121,7 @@ namespace MP.Land.Pages
protected string localPath(string localRepo)
{
return @$"{Configuration["downloadPath"]}\{localRepo}\{Configuration["appVers"]}"; ;
return @$"{Configuration["ServerConf:downloadPath"]}\{localRepo}\{Configuration["appVers"]}"; ;
}
protected override void OnInitialized()
+1 -1
View File
@@ -34,7 +34,7 @@ namespace MP.Land.Pages
protected string BaseUrlTab
{
get => $"{Configuration["BaseUrl"]}{Configuration["QrJumpPath"]}";
get => $"{Configuration["ServerConf:BaseUrl"]}{Configuration["QrJumpPath"]}";
}
[Inject]
+1 -1
View File
@@ -1,6 +1,6 @@
<body>
<i>Modulo gestione Programmi MAPO</i>
<h4>Versione: 6.15.2207.0718</h4>
<h4>Versione: 6.15.2209.1212</h4>
<br />
Note di rilascio:
<ul>
+1 -1
View File
@@ -1 +1 @@
6.15.2207.0718
6.15.2209.1212
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<item>
<version>6.15.2207.0718</version>
<version>6.15.2209.1212</version>
<url>https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/MP.Land.zip</url>
<changelog>https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/ChangeLog.html</changelog>
<mandatory>false</mandatory>
+20 -18
View File
@@ -1,21 +1,23 @@
{
"DetailedErrors": true,
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"Environment": "Steam PROD",
"BaseUrl": "https://iis02.egalware.com/",
"AllowedHosts": "*",
"QrJumpPath": "MP/TAB/jumper?",
"downloadPath": "C:\\Steamware\\installers\\MP",
"appVers": "stable",
"ConnectionStrings": {
"DefaultConnection": "Server=SQL2016DEV;Database=MoonPro;Trusted_Connection=True;MultipleActiveResultSets=true",
"MP.Land": "Server=SQL2016DEV;Database=MoonPro;User ID=sa;Password=keyhammer16;integrated security=False;MultipleActiveResultSets=True;App=MP.Land;",
"Redis": "localhost:6379,defaultDatabase=1,keepAlive=180,asyncTimeout=5000"
"DetailedErrors": true,
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"Environment": "Steam PROD",
"AllowedHosts": "*",
"QrJumpPath": "MP/TAB/jumper?",
"appVers": "stable",
"ConnectionStrings": {
"DefaultConnection": "Server=SQL2016DEV;Database=MoonPro;Trusted_Connection=True;MultipleActiveResultSets=true",
"MP.Land": "Server=SQL2016DEV;Database=MoonPro;User ID=sa;Password=keyhammer16;integrated security=False;MultipleActiveResultSets=True;App=MP.Land;",
"Redis": "localhost:6379,defaultDatabase=1,keepAlive=180,asyncTimeout=5000"
},
"ServerConf": {
"BaseUrl": "https://iis02.egalware.com/",
"downloadPath": "C:\\Steamware\\installers\\MP"
}
}
+4 -1
View File
@@ -8,5 +8,8 @@
}
},
"Environment": "Steam DEV",
"BaseUrl": "https://iis01.egalware.com/"
"ServerConf": {
"BaseUrl": "https://iis01.egalware.com/",
"downloadPath": "C:\\Steamware\\installers\\MP"
}
}
+4 -2
View File
@@ -7,15 +7,17 @@
}
},
"AllowedHosts": "*",
"BaseUrl": "https://localhost:44309/",
"QrJumpPath": "MP/TAB/jumper?",
"Environment": "Steam DEV",
"downloadPath": "C:\\Steamware\\installers\\MP",
"appVers": "stable",
"ConnectionStrings": {
"DefaultConnection": "Server=SQL2016DEV;Database=MoonPro;Trusted_Connection=True;MultipleActiveResultSets=true",
"MP.Land": "Server=SQL2016DEV;Database=MoonPro;User ID=sa;Password=keyhammer16;integrated security=False;MultipleActiveResultSets=True;App=MP.Land;",
"Redis": "localhost:6379,defaultDatabase=1,keepAlive=180,asyncTimeout=5000"
},
"ServerConf": {
"BaseUrl": "https://localhost:44309/",
"downloadPath": "C:\\Steamware\\installers\\MP"
}
//"ConnectionStrings": {
// "DefaultConnection": "Server=SQL2016PROD;Database=Jetco_MoonPro_Prod;Trusted_Connection=True;MultipleActiveResultSets=true",
+1 -1
View File
@@ -1,6 +1,6 @@
<div class="px-2">
<img class="logoImg img-fluid" src="images/LogoMapo.png" height="24" />
<span class="mainHead p-3"><b><span style="color: #DEDEDE;">MP MON</span>itor</b></span>
<span class="mainHead p-3 align-middle"><b><span style="color: #DEDEDE;">MP MON</span>itor</b></span>
</div>
<div class="px-2">
<span id="text-white text-right">
+24 -40
View File
@@ -12,11 +12,6 @@ namespace MP.Mon.Components
[Parameter]
public MappaStatoExpl? CurrRecord { get; set; } = null;
/// <summary>
/// Valore precedente x calcolo variazione
/// </summary>
private MappaStatoExpl? OldRecord { get; set; } = null;
[Parameter]
public List<TagData>? currTagConf { get; set; } = null;
@@ -26,37 +21,22 @@ namespace MP.Mon.Components
[Parameter]
public bool doAnimate { get; set; } = true;
[Parameter]
public bool doBlink { get; set; } = false;
[Parameter]
public int keepAliveMin { get; set; } = 5;
[Parameter]
public string showArt { get; set; } = "";
[Parameter]
public bool doBlink { get; set; } = false;
//{
// set
// {
// // se true --> ricarica
// if (value)
// {
// var pUpd = Task.Run(async () =>
// {
// await InvokeAsync(() => StateHasChanged());
// });
// pUpd.Wait();
// }
// }
//}
#endregion Public Properties
#region Public Methods
public void Dispose()
{
//aTimer.Elapsed -= ElapsedTimer;
aTimer.Elapsed -= ElapsedTimer;
aTimer.Stop();
aTimer.Dispose();
}
@@ -88,10 +68,6 @@ namespace MP.Mon.Components
}
if (needUpdate)
{
if (false)
{
Log.Trace($"Elapsed Timer {CurrRecord?.CodMacchina}");
}
await InvokeAsync(() => StateHasChanged());
}
OldRecord = CurrRecord;
@@ -114,6 +90,7 @@ namespace MP.Mon.Components
#region Protected Fields
protected string baseCss = "sem";
protected int kaFactor = 60 / 2;
#endregion Protected Fields
@@ -209,11 +186,21 @@ namespace MP.Mon.Components
#region Private Fields
private static System.Timers.Timer aTimer { get; set; } = null!;
private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
#endregion Private Fields
#region Private Properties
private static System.Timers.Timer aTimer { get; set; } = null!;
/// <summary>
/// Valore precedente x calcolo variazione
/// </summary>
private MappaStatoExpl? OldRecord { get; set; } = null;
#endregion Private Properties
#region Private Methods
private string cssComStatus(string semaforo, DateTime? lastUpdateN)
@@ -246,16 +233,6 @@ namespace MP.Mon.Components
string answ = $"{baseCss}{codColore}";
if (doAnimate && codColore != "Ve")
{
#if false
// blink se secondo pari...
DateTime adesso = DateTime.Now;
int resto = 0;
Math.DivRem(adesso.Second, 2, out resto);
if (resto == 0)
{
answ += "_b";
}
#endif
if (doBlink)
{
answ += "_b";
@@ -282,7 +259,14 @@ namespace MP.Mon.Components
{
double cTimeMin = currTimeMin != null ? (double)currTimeMin : 0;
tSpan = TimeSpan.FromMinutes(cTimeMin);
answ = $"{tSpan:mm}:{tSpan:ss}";
if (tSpan.TotalHours < 1)
{
answ = $"{tSpan:mm}:{tSpan:ss}";
}
else
{
answ = $"{tSpan.TotalHours:N0}h {tSpan:mm}:{tSpan:ss}";
}
}
catch
{ }
+7 -3
View File
@@ -1,6 +1,10 @@
<div class="row p-5 m-5 bg-light">
<div class="col-12 text-center mt-5 py-5 alert alert-primary">
<div class="row p-5 m-5 alert alert-primary">
<div class="col-6 text-center mt-4 py-3 bg-light">
<h1>MAPO MON</h1>
EgalWare MES suite <img class="logoImg img-fluid" src="images/logoCliente.png" />
</div>
<div class="col-6 text-center mt-4 py-3 bg-light">
<h3>loading data</h3>
<i class="fas fa-spinner fa-spin fa-5x"></i>
<i class="fas fa-spinner fa-spin fa-4x"></i>
</div>
</div>
+79 -14
View File
@@ -1,4 +1,5 @@
using MP.Data.Conf;
using MP.Data;
using MP.Data.Conf;
using MP.Data.DatabaseModels;
using Newtonsoft.Json;
using NLog;
@@ -18,10 +19,11 @@ namespace MP.Mon.Data
_configuration = configuration;
// setup compoenti REDIS
this.redisConn = ConnectionMultiplexer.Connect(_configuration.GetConnectionString("Redis"));
this.redisDb = this.redisConn.GetDatabase();
//// setup canali pub/sub
//actLogPipe = new MessagePipe(redisConn, Constants.ACT_LOG_M_QUEUE);
redisConn = ConnectionMultiplexer.Connect(_configuration.GetConnectionString("Redis"));
redisDb = redisConn.GetDatabase();
// setup canali pub/sub
dataPipe = new MessagePipe(redisConn, Constants.ACT_MSE_DATA_KEY);
blinkPipe = new MessagePipe(redisConn, Constants.ACT_BLINK_KEY);
// conf DB
string connStr = _configuration.GetConnectionString("Mp.Mon");
@@ -34,12 +36,14 @@ namespace MP.Mon.Data
dbController = new MP.Data.Controllers.MpMonController(configuration);
StringBuilder sb = new StringBuilder();
sb.AppendLine($"DbController OK");
//sb.AppendLine($"CST: {dbController.CustomersCount()} | CNT: {dbController.CountersCount()} | BSK: {dbController.BasketsCount()} | NGT: {dbController.NegotiationsCount()} | DOC: {dbController.DocsCount()} | ITM: {dbController.ItemsCount()} | RES: {dbController.ResourcesCount()}");
_logger.LogInformation(sb.ToString());
}
// setup conf IOB da dizionario
tryLoadIobTags();
// avvio timers...
startTimers();
}
#endregion Public Constructors
@@ -48,11 +52,15 @@ namespace MP.Mon.Data
public static MP.Data.Controllers.MpMonController dbController { get; set; } = null!;
public MessagePipe blinkPipe { get; set; } = null!;
/// <summary>
/// Dizionario dei tag configurati per IOB
/// </summary>
public Dictionary<string, List<TagData>> currTagConf { get; set; } = new Dictionary<string, List<TagData>>();
public MessagePipe dataPipe { get; set; } = null!;
#endregion Public Properties
#region Public Methods
@@ -68,6 +76,14 @@ namespace MP.Mon.Data
dbController.Dispose();
}
/// <summary>
/// Richiesta attivazione --&gt; sposto avanti 1 minuto il periodo limite x fast running
/// </summary>
public void doActivate()
{
fastLimit = DateTime.Now.AddMinutes(1);
}
/// <summary>
/// Elenco setup dei tag conf correnti
/// </summary>
@@ -101,27 +117,29 @@ namespace MP.Mon.Data
public async Task<List<MappaStatoExpl>> MseGetAll()
{
int maxAge = 2000;
int.TryParse(_configuration.GetValue<string>("ServerConf:maxAge"), out maxAge);
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
List<MappaStatoExpl> result = new List<MappaStatoExpl>();
List<MappaStatoExpl>? result = new List<MappaStatoExpl>();
// cerco in redis...
var rawData = await redisDb.StringGetAsync(redisMseKey);
if (!string.IsNullOrEmpty(rawData))
RedisValue rawData = await redisDb.StringGetAsync(redisMseKey);
if (!string.IsNullOrEmpty($"{rawData}"))
{
result = JsonConvert.DeserializeObject<List<MappaStatoExpl>>(rawData);
result = JsonConvert.DeserializeObject<List<MappaStatoExpl>>($"{rawData}");
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Trace($"Read from REDIS: {ts.TotalMilliseconds}ms");
Log.Debug($"Read from REDIS: {ts.TotalMilliseconds}ms");
}
else
{
result = await Task.FromResult(dbController.MseGetAll());
result = await Task.FromResult(dbController.MseGetAll(maxAge));
// serializzp e salvo...
rawData = JsonConvert.SerializeObject(result);
await redisDb.StringSetAsync(redisMseKey, rawData, TimeSpan.FromSeconds(2));
await redisDb.StringSetAsync(redisMseKey, rawData, TimeSpan.FromMilliseconds(maxAge));
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Trace($"Read from DB: {ts.TotalMilliseconds}ms");
Log.Debug($"Read from DB: {ts.TotalMilliseconds}ms");
}
if (result == null)
{
@@ -135,10 +153,21 @@ namespace MP.Mon.Data
#region Private Fields
private static IConfiguration _configuration = null!;
private static ILogger<MpDataService> _logger = null!;
private static System.Timers.Timer fastTimer = new System.Timers.Timer(4000);
private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
/// <summary>
/// Limite in formato data-ora per inviare dati rapidamente (incrementato come now + 1 min
/// ad ogni chiamata client)
/// </summary>
private DateTime fastLimit = DateTime.Now;
private int fastRefreshMs = 1000;
/// <summary>
/// Oggetto per connessione a REDIS
/// </summary>
@@ -156,6 +185,42 @@ namespace MP.Mon.Data
#region Private Methods
private void ElapsedFastTimer(object? source, System.Timers.ElapsedEventArgs e)
{
var pUpd = Task.Run(async () =>
{
// secondi pari --> blink, secondi dispari --> ricarica
DateTime adesso = DateTime.Now;
int resto = 0;
Math.DivRem(adesso.Second, 2, out resto);
if (resto == 0)
{
// invio in channel blink il segnale
blinkPipe.sendMessage("true");
Log.Debug("Elapsed Fast Timer Blink");
}
else
{
// invio in channel blink segnale false
blinkPipe.sendMessage("false");
// rileggo dati...
var newData = await MseGetAll();
// invio tramite la pipe...
dataPipe.sendMessage(JsonConvert.SerializeObject(newData));
Log.Debug("Elapsed Fast Timer reload");
}
});
pUpd.Wait();
}
private void startTimers()
{
fastTimer = new System.Timers.Timer(fastRefreshMs);
fastTimer.Elapsed += ElapsedFastTimer;
fastTimer.Enabled = true;
fastTimer.Start();
}
/// <summary>
/// Prova a caricare da file la conf degli IOB se presente
/// </summary>
+1 -1
View File
@@ -4,7 +4,7 @@
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<Version>6.15.2207.1217</Version>
<Version>6.15.2209.1411</Version>
</PropertyGroup>
<ItemGroup>
+1 -1
View File
@@ -39,7 +39,7 @@
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="*" minlevel="Debug" writeTo="consoleTarget" />
<!--<logger name="Microsoft.*" maxlevel="Info" final="true" />-->
<logger name="*" minlevel="Info" writeTo="fileTarget" />
</rules>
-1
View File
@@ -5,7 +5,6 @@
<PageTitle>MP MON</PageTitle>
<div class="row statusMap mx-1 my-1">
@if (listMSE == null)
{
<div class="col-12">
+85 -58
View File
@@ -1,7 +1,9 @@
using Microsoft.AspNetCore.Components;
using MP.Data;
using MP.Data.Conf;
using MP.Data.DatabaseModels;
using MP.Mon.Data;
using Newtonsoft.Json;
using NLog;
namespace MP.Mon.Pages
@@ -12,58 +14,23 @@ namespace MP.Mon.Pages
public void Dispose()
{
#if false
fastTimer.Stop();
fastTimer.Dispose();
slowTimer.Stop();
slowTimer.Dispose();
#endif
disposeTimers();
}
public void ElapsedFastTimer(object? source, System.Timers.ElapsedEventArgs e)
{
var pUpd = Task.Run(async () =>
{
// secondi pari --> blink, secondi dispari --> ricarica
DateTime adesso = DateTime.Now;
int resto = 0;
Math.DivRem(adesso.Second, 2, out resto);
if (resto == 0)
{
doBlink = true;
Log.Trace("Elapsed Fast Timer Blink");
}
else
{
doBlink = false;
await ReloadData();
Log.Trace("Elapsed Fast Timer reload");
}
await Task.Delay(1);
await InvokeAsync(StateHasChanged);
});
pUpd.Wait();
}
public async void ElapsedSlowTimer(object? source, System.Timers.ElapsedEventArgs e)
{
listMSE = null;
await Task.Delay(1);
await Task.Delay(10);
Log.Info("Elapsed Slow Timer --> full page reload");
// dispongo i vari timers...
disposeTimers();
await Task.Delay(10);
// reload pagina
NavManager.NavigateTo(NavManager.Uri);
}
public void StartTimer()
{
// timer veloce
fastTimer = new System.Timers.Timer(fastRefreshMs);
fastTimer.Elapsed += ElapsedFastTimer;
fastTimer.Enabled = true;
fastTimer.Start();
// timer lento
slowTimer = new System.Timers.Timer(slowRefreshMs);
slowTimer.Elapsed += ElapsedSlowTimer;
@@ -94,7 +61,12 @@ namespace MP.Mon.Pages
protected int slowRefreshMs
{
get => 1000 * slowRefreshSec;
get
{
// tempo variabile tra +/- 10% del target
int answ = rnd.Next(900, 1100) * slowRefreshSec;
return answ;
}
}
#endregion Protected Properties
@@ -185,50 +157,105 @@ namespace MP.Mon.Pages
protected override async Task OnInitializedAsync()
{
await setupConf();
await ReloadData();
MMDataService.dataPipe.EA_NewMessage += DataPipe_EA_NewMessage;
MMDataService.blinkPipe.EA_NewMessage += BlinkPipe_EA_NewMessage;
Random rnd = new Random();
await Task.Delay(rnd.Next(1000, 1200));
StartTimer();
}
#endregion Protected Methods
#region Private Fields
private static System.Timers.Timer fastTimer = new System.Timers.Timer(4000);
//private static System.Timers.Timer fastTimer = new System.Timers.Timer(4000);
private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
private static System.Timers.Timer slowTimer = new System.Timers.Timer(300000);
private List<ConfigModel>? CurrConfig = null;
private bool doBlink = false;
private List<MappaStatoExpl>? listMSE = null;
private Random rnd = new Random();
#endregion Private Fields
#region Private Methods
private void BlinkPipe_EA_NewMessage(object? sender, EventArgs e)
{
PubSubEventArgs currArgs = (PubSubEventArgs)e;
// conversione on-the-fly List<string> --> allarmi
if (!string.IsNullOrEmpty(currArgs.newMessage))
{
try
{
var dataRaw = JsonConvert.DeserializeObject<string>(currArgs.newMessage);
if (dataRaw != null)
{
bool.TryParse($"{dataRaw}", out doBlink);
}
}
catch
{ }
InvokeAsync(() =>
{
StateHasChanged();
});
}
}
/// <summary>
/// Ricevuto nuovi dati da mostrare!
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <exception cref="NotImplementedException"></exception>
private void DataPipe_EA_NewMessage(object? sender, EventArgs e)
{
PubSubEventArgs currArgs = (PubSubEventArgs)e;
// conversione on-the-fly List<string> --> allarmi
if (!string.IsNullOrEmpty(currArgs.newMessage))
{
try
{
var dataList = JsonConvert.DeserializeObject<List<MappaStatoExpl>>(currArgs.newMessage);
if (dataList != null)
{
#if DEBUG
// hack: legge 4 volte i dati x stressare sistema
var singleData = dataList;
listMSE = new List<MappaStatoExpl>();
for (int i = 0; i < 4; i++)
{
listMSE.AddRange(singleData);
}
#else
listMSE = dataList;
#endif
}
}
catch
{ }
}
InvokeAsync(() =>
{
#if false
// attesa random 0-50ms...
Random rnd = new Random();
Task.Delay(rnd.Next(5, 50));
#endif
StateHasChanged();
});
}
private void disposeTimers()
{
fastTimer.Elapsed -= ElapsedFastTimer;
fastTimer.Stop();
fastTimer.Dispose();
slowTimer.Elapsed -= ElapsedSlowTimer;
slowTimer.Stop();
slowTimer.Dispose();
}
private async Task ReloadData()
{
#if DEBUG
// hack: legge 4 volte i dati x stressare sistema
var singleData = await MMDataService.MseGetAll();
listMSE = new List<MappaStatoExpl>();
for (int i = 0; i < 4; i++)
{
listMSE.AddRange(singleData);
}
#else
listMSE = await MMDataService.MseGetAll();
#endif
}
private async Task setupConf()
{
CurrConfig = await MMDataService.ConfigGetAll();
+19 -14
View File
@@ -7,6 +7,7 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="google" content="notranslate">
<base href="~/" />
<link rel="stylesheet" href="lib/bootstrap/css/bootstrap.min.css" />
<link rel="stylesheet" href="css/site.css" />
@@ -28,24 +29,28 @@
<a class="dismiss">🗙</a>
</div>
<script src="_framework/blazor.server.js" autostart="false"></script>
@*Gestione autoriconnessione: https://github.com/dotnet/aspnetcore/issues/38305 (vedere anche https://docs.microsoft.com/it-it/aspnet/core/blazor/fundamentals/signalr?view=aspnetcore-6.0#modify-the-reconnection-handler-blazor-server)*@
<script>
Blazor.start().then(() => {
Object.defineProperty(Blazor.defaultReconnectionHandler, '_reconnectionDisplay', {
get() {
return this.__reconnectionDisplay;
},
set(value) {
this.__reconnectionDisplay = {
show: () => value.show(),
update: (d) => value.update(d),
rejected: (d) => document.location.reload()
Blazor.start({
reconnectionOptions: {
maxRetries: 300,
retryIntervalMilliseconds: 2000
}
}).then(() => {
Object.defineProperty(Blazor.defaultReconnectionHandler, '_reconnectionDisplay', {
get() {
return this.__reconnectionDisplay;
},
set(value) {
this.__reconnectionDisplay = {
show: () => value.show(),
update: (d) => value.update(d),
rejected: (d) => document.location.reload()
}
}
}
});
});
});
</script>
<script src="_framework/blazor.server.js"></script>
</body>
</html>
+1 -1
View File
@@ -1,6 +1,6 @@
<body>
<i>Modulo MON MAPO</i>
<h4>Versione: 6.15.2207.1217</h4>
<h4>Versione: 6.15.2209.1411</h4>
<br /> Note di rilascio:
<ul>
<li>
+1 -1
View File
@@ -1 +1 @@
6.15.2207.1217
6.15.2209.1411
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<item>
<version>6.15.2207.1217</version>
<version>6.15.2209.1411</version>
<url>https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/MP.Mon.zip</url>
<changelog>https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/ChangeLog.html</changelog>
<mandatory>false</mandatory>
+2 -2
View File
@@ -13,14 +13,14 @@ main {
/*border-bottom: 1px solid #696969;*/
color: #696969;
font-size: 1.4em;
height: 3rem;
height: 2.6rem;
display: flex;
align-items: center;
justify-content: space-evenly;
}
.mainHead{
font-size: 1.7rem;
font-size: 1.6rem;
}
.top-row ::deep a,
+3
View File
@@ -11,5 +11,8 @@
"MP.Mon": "Server=SQL2016DEV;Database=MoonPro; User ID=sa;Password=keyhammer16; integrated security=False; MultipleActiveResultSets=True; App=Blazor.ServerApp;",
"MP.Stats": "Server=SQL2016DEV;Database=MoonPro_STATS; User ID=sa;Password=keyhammer16; integrated security=False; MultipleActiveResultSets=True; App=Blazor.ServerApp;",
"Redis": "localhost:6379,DefaultDatabase=1,connectTimeout=5000,syncTimeout=5000,asyncTimeout=5000,abortConnect=false,ssl=false"
},
"ServerConf": {
"maxAge": "2000"
}
}
+1 -1
View File
@@ -308,7 +308,7 @@ a,
/* Gestione size caratteri */
.mainHead,
.logoImg {
height: 1.6em;
height: 1.5em;
}
@media all and (min-width: 425px) {
.mainHead {
+1 -1
View File
@@ -3,7 +3,7 @@
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace>MP.Prog</RootNamespace>
<Version>6.15.2202.2715</Version>
<Version>6.15.2209.1609</Version>
</PropertyGroup>
<ItemGroup>
+1 -1
View File
@@ -1,6 +1,6 @@
<body>
<i>Modulo gestione Programmi MAPO</i>
<h4>Versione: 6.15.2202.2715</h4>
<h4>Versione: 6.15.2209.1609</h4>
<br />
Note di rilascio:
<ul>
+1 -1
View File
@@ -1 +1 @@
6.15.2202.2715
6.15.2209.1609
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<item>
<version>6.15.2202.2715</version>
<version>6.15.2209.1609</version>
<url>https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/MP.Prog.zip</url>
<changelog>https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/ChangeLog.html</changelog>
<mandatory>false</mandatory>
+14
View File
@@ -0,0 +1,14 @@
<CascadingAuthenticationState>
<Router AppAssembly="@typeof(App).Assembly">
<Found Context="routeData">
<AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
</Found>
<NotFound>
<PageTitle>Not found</PageTitle>
<LayoutView Layout="@typeof(MainLayout)">
<p role="alert">Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
</CascadingAuthenticationState>
+9
View File
@@ -0,0 +1,9 @@
<div class="row text-light">
<div class="col-5 pe-0 text-left">
<b>Mapo SPEC @(DateTime.Today.Year)</b> | <span class="small">v.@version</span>
</div>
<div class="col-7 ps-0 text-end">
<span class="small">@($"{DateTime.Now:HH:mm:ss}")</span> | <a class="text-light" href="https://www.egalware.com/" target="_blank"><img class="img-fluid" width="16" src="images/LogoEgw.png" /> Egalware </a>
</div>
</div>
+55
View File
@@ -0,0 +1,55 @@
using NLog;
namespace MP.SPEC.Components
{
public partial class CmpFooter
{
#region Public Methods
public void Dispose()
{
aTimer.Elapsed -= ElapsedTimer;
aTimer.Stop();
aTimer.Dispose();
}
public void ElapsedTimer(object? source, System.Timers.ElapsedEventArgs e)
{
var pUpd = Task.Run(async () =>
{
await Task.Delay(1);
await InvokeAsync(() => StateHasChanged());
});
pUpd.Wait();
}
public void StartTimer()
{
int tOutPeriod = 5000;
//int.TryParse(Configuration["ReloadStatusTimer"], out tOutPeriod);
aTimer = new System.Timers.Timer(tOutPeriod);
aTimer.Elapsed += ElapsedTimer;
aTimer.Enabled = true;
aTimer.Start();
}
protected override void OnInitialized()
{
version = typeof(Program).Assembly.GetName().Version;
}
#endregion Public Methods
#region Protected Methods
#endregion Protected Methods
#region Private Fields
private static System.Timers.Timer aTimer = null!;
private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
private Version version = null!;
#endregion Private Fields
}
}
+65
View File
@@ -0,0 +1,65 @@
@using MP.SPEC.Components
@using MP.SPEC.Data
@using System.Security.Claims
@using Microsoft.AspNetCore.Components.Authorization
@inject AuthenticationStateProvider AuthenticationStateProvider
@inject MessageService MService
<div class="d-flex w-100 justify-content-between">
<div class="px-2">
<i class="fas fa-user-alt"></i> <b>@userName</b>
</div>
<div class="px-2 flex-grow-1 text-end">
<span class="text-secondary">@TipoSearch</span>
</div>
<div class="px-2 text-end">
@if (ShowSearch)
{
<SearchMod></SearchMod>
}
</div>
</div>
@code {
protected bool ShowSearch
{
get => MService.ShowSearch;
set => MService.ShowSearch = value;
}
private string userName = "";
private string TipoSearch
{
get => MService.TipoSearch;
set => MService.TipoSearch = value;
}
protected override async Task OnInitializedAsync()
{
MService.EA_ShowSearch += MService_EA_ShowSearch;
await forceReload();
}
private async void MService_EA_ShowSearch()
{
await Task.Delay(1);
await InvokeAsync(() => StateHasChanged());
}
private async Task forceReload()
{
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
var user = authState.User;
if (user.Identity != null&& user.Identity.IsAuthenticated)
{
userName = $"{user.Identity.Name}";
}
else
{
userName = "N.A.";
}
}
}
+56
View File
@@ -0,0 +1,56 @@
<div class="row">
<div class="col-12 col-lg-8 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-4">
<div class="d-flex">
<div class="p-1 flex-fill">
@if (!showLoading)
{
<span>@totalCount records</span>
}
</div>
<div class="p-1 small">
@if (totalCount > 0)
{
<div class="input-group input-group-sm">
<select @bind="@PageSize" class="form-select form-select-sm text-end">
<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>
+194
View File
@@ -0,0 +1,194 @@
using Microsoft.AspNetCore.Components;
namespace MP.SPEC.Components
{
public partial class DataPager : ComponentBase
{
#region Public Properties
[Parameter]
public int currPage
{
get
{
return _numPage;
}
set
{
bool doReport = !_numPage.Equals(value);
if (doReport)
{
_numPage = value;
reportChangePage();
}
}
}
public async Task resetCurrPage()
{
await Task.Delay(1);
currPage = 1;
}
[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();
resetCurrPage();
}
}
}
[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 Protected Fields
protected bool _showLoading = false;
#endregion Protected Fields
#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 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
#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 Private Methods
private void reportChange()
{
numRecordChanged.InvokeAsync(PageSize);
}
private void reportChangePage()
{
numPageChanged.InvokeAsync(currPage);
}
#endregion Private Methods
}
}
+77
View File
@@ -0,0 +1,77 @@
<div class="d-flex justify-content-between">
<div class="px-0 py-1">
</div>
<div class="px-0 col-6">
<div class="">
@*@if (showEditPar)
{
<div class="px-0 input-group py-1" id="basic-addon1">
<button class="btn btn-primary" @onclick="() => toggleParams()"> <i class="fa-solid fa-arrow-right"></i></button>
<label class="input-group-text" for="tempoAgg" title="Selezionare il tempo di aggiornamento dei dati"><i class="fa-solid fa-clock"></i></label>
<select @bind="@selTempoAgg" class="form-select" id="tempoAgg" title="Selezionare il tempo di aggiornamento dei dati">
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
<option value="9">9</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
<option value="13">13</option>
<option value="14">14</option>
<option value="15">15</option>
<option value="16">16</option>
<option value="17">17</option>
<option value="18">18</option>
<option value="19">19</option>
<option value="20">20</option>
</select>
<label class="input-group-text" for="maxRecord" title="Selezionare il numero massimo di record da visualizzare"><i class="fa-solid fa-list-ol"></i></label>
<select @bind="@selMaxRecord" class="form-select" id="maxRecord" title="Selezionare il numero massimo di record da visualizzare">
<option value="50">50</option>
<option value="100">100</option>
<option value="150">150</option>
<option value="200">200</option>
<option value="250">250</option>
<option value="300">300</option>
<option value="350">350</option>
<option value="400">400</option>
<option value="450">450</option>
<option value="500">500</option>
</select>
</div>
}
else
{
<div class="px-2 py-1">
<button class="btn btn-primary" @onclick="() => toggleParams()"><i class="fa-solid fa-arrow-left"></i></button>
</div>
}*@
<div class="px-0 py-1">
<div class="px-2 input-group" id="basic-addon1">
<label class="input-group-text" for="macchina" title="Selezionare la macchina"><i class="fa-solid fa-hard-drive"></i></label>
<select @bind="@selMacchina" class="form-select" id="macchina" title="Selezionare la macchina">
<option value="*">--- Tutti ---</option>
@if (ListMacchine != null)
{
foreach (var item in ListMacchine)
{
<option value="@item">@item</option>
}
}
</select>
<label class="input-group-text" for="DtRef" title="Selezionare il tipo di flusso"><i class="fa-solid fa-calendar-check"></i></label>
<input @bind="@selDtRef" id="DtRef" class="form-control" type="datetime-local" />
</div>
</div>
</div>
</div>
</div>
+139
View File
@@ -0,0 +1,139 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
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.SPEC;
using MP.SPEC.Shared;
using MP.SPEC.Components;
using MP.SPEC.Data;
using MP.Data.DatabaseModels;
namespace MP.SPEC.Components
{
public partial class DossiersFilter
{
#region Public Properties
[Parameter]
public EventCallback<SelectDossierParams> FilterChanged { get; set; }
[Parameter]
public SelectDossierParams SelFilterDossier { get; set; } = null!;
#endregion Public Properties
#region Protected Fields
#endregion Protected Fields
#region Protected Properties
[Inject]
protected MpDataService MDService { get; set; } = null!;
protected string selMacchina
{
get
{
return SelFilterDossier.IdxMacchina;
}
set
{
if (!SelFilterDossier.IdxMacchina.Equals(value))
{
SelFilterDossier.CurrPage = 1;
SelFilterDossier.IdxMacchina = value;
StateHasChanged();
Task.Delay(1);
reportChange();
}
}
}
protected int selMaxRecord
{
get
{
return SelFilterDossier.MaxRecord;
}
set
{
if (!SelFilterDossier.MaxRecord.Equals(value))
{
SelFilterDossier.MaxRecord = value;
reportChange();
}
}
}
protected DateTime selDtRef
{
get
{
return SelFilterDossier.DtRef;
}
set
{
if (!SelFilterDossier.DtRef.Equals(value))
{
SelFilterDossier.DtRef = value;
reportChange();
}
}
}
#endregion Protected Properties
#region Protected Methods
protected override async Task OnInitializedAsync()
{
SelFilterDossier = new SelectDossierParams();
ListMacchine = await MDService.MacchineWithFlux();
ListDossier = await MDService.DossiersGetLastFilt(selMacchina, selDtRef, selMaxRecord);
await FilterChanged.InvokeAsync(SelFilterDossier);
}
protected void toggleParams()
{
showEditPar = !showEditPar;
}
#endregion Protected Methods
#region Private Fields
private List<Dossiers>? ListDossier = null;
private List<string>? ListMacchine = null;
#endregion Private Fields
#region Private Properties
private bool showEditPar { get; set; } = false;
#endregion Private Properties
#region Private Methods
private void reportChange()
{
FilterChanged.InvokeAsync(SelFilterDossier);
}
#endregion Private Methods
}
}
+103
View File
@@ -0,0 +1,103 @@
@using MP.SPEC.Components
@using MP.SPEC.Data
@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="d-flex justify justify-content-between">
<table class="table table-sm table-striped small">
<thead>
<tr>
<th>
<button @onclick="() => unToggleTableFlux()" class="btn btn-primary btn-sm"><i class="bi bi-arrow-counterclockwise"></i></button>
</th>
<th><i class="fa-solid fa-hard-drive"></i> Macchina</th>
<th><i class="fa-regular fa-calendar-days"></i> Data</th>
<th><i class="fa-solid fa-sliders"></i> ODL</th>
<th><i class="fa-solid fa-sliders"></i> DATA TYPE</th>
</tr>
</thead>
<tbody>
@foreach (var record in ListRecords)
{
<tr class="@checkSelect(@record)">
<td>
<button class="btn btn-primary btn-sm" @onclick="() => selRecord(record)"><i class="fa-solid fa-magnifying-glass"></i></button>
</td>
<td>
@record.IdxMacchina
</td>
<td>
@record.DtRif
</td>
<td>
@record.IdxODL
</td>
<td>
@record.DataType
</td>
</tr>
}
</tbody>
</table>
@if (!visualizzaFlux)
{
if (listaFlux == null)
{
<div class="alert alert-warning text-center display-4">Nessun record trovato</div>
}
else
{
<div class="table selBlock p-2">
<table class="table table-light table-sm table-striped small mb-0">
<thead>
<tr>
<th><i class="fa-solid fa-hard-drive"></i> Macchina</th>
<th><i class="fa-regular fa-calendar-days"></i> Data</th>
<th><i class="fa-solid fa-sliders"></i> ODL</th>
<th class="d-flex justify-content-between"><i class="fa-solid fa-sliders"></i> Valore <button class="btn btn-primary btn-sm py-0" @onclick="() => unToggleTableFlux()"><i class="fa-solid fa-xmark"></i></button></th>
@*<th class="d-flex justify-content-end"><button class="btn btn-primary btn-sm py-0" @onclick="() => unToggleTableFlux()"><i class="fa-solid fa-xmark"></i></button></th>*@
</tr>
</thead>
<tbody>
@foreach (var record in listaFlux)
{
<tr>
<td>
@record.IdxMacchina
</td>
<td>
@record.dtEvento
</td>
<td>
@record.CodFlux
</td>
<td style="text-align: right;">
<b>@record.Valore</b>
</td>
@* <td>
</td>*@
</tr>
}
</tbody>
</table>
</div>
}
}
</div>
</div>
}
+197
View File
@@ -0,0 +1,197 @@
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using MP.Data.DatabaseModels;
using MP.SPEC.Data;
namespace MP.SPEC.Components
{
public partial class ListDossiers
{
#region Public Properties
[Parameter]
public EventCallback<Dossiers> RecordSel { get; set; }
[Parameter]
public SelectDossierParams SelFilter { get; set; } = null!;
[Parameter]
public EventCallback<int> TotRecordChanged { get; set; }
#endregion Public Properties
#region Public Methods
public string checkSelect(Dossiers recordSel)
{
string answ = "";
if (currRecord != null)
{
try
{
answ = (currRecord.IdxMacchina == recordSel.IdxMacchina && currRecord.DtRif == recordSel.DtRif) ? "table-info" : "";
}
catch
{ }
}
return answ;
}
public async Task reloadData(bool setChanged)
{
isLoading = true;
SearchRecords = await MDService.DossiersGetLastFilt(SelMacchina, SelDtRef, MaxRecord);
totalCount = SearchRecords.Count;
ListRecords = SearchRecords.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList();
await Task.Delay(1);
if (setChanged)
{
await InvokeAsync(() => StateHasChanged());
}
isLoading = false;
}
#endregion Public Methods
#region Protected Properties
[Inject]
protected IJSRuntime JSRuntime { get; set; } = null!;
[Inject]
protected MpDataService MDService { get; set; } = null!;
[Inject]
protected MessageService MessageService { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected override async Task OnInitializedAsync()
{
MessageService.EA_PageUpdated += MessageService_EA_PageUpdated;
MessageService.EA_SearchUpdated += OnSeachUpdated;
ListRecords = await MDService.DossiersGetLastFilt(SelMacchina, SelDtRef, MaxRecord);
await reloadData();
}
protected async void OnSeachUpdated()
{
await InvokeAsync(() =>
{
currPage = 1;
StateHasChanged();
});
}
protected async Task selRecord(Dossiers selRec)
{
currRecord = selRec;
await RecordSel.InvokeAsync(selRec);
listaFlux = MDService.convertToFluxLog(selRec.Valore);
await toggleTableFlux();
}
protected async Task UpdateData()
{
currRecord = null;
await reloadData(true);
}
#endregion Protected Methods
#region Private Fields
private int _totalCount = 0;
private Dossiers? currRecord = null;
private List<Dossiers>? ListRecords;
private List<Dossiers>? SearchRecords;
#endregion Private Fields
#region Private Properties
private int currPage
{
get => MessageService.currPage;
set => MessageService.currPage = value;
}
private bool isLoading { get; set; } = false;
private List<FluxLog>? listaFlux { get; set; } = null;
private int MaxRecord
{
get => SelFilter.MaxRecord;
}
private int numRecord
{
get => MessageService.numRecord;
set => MessageService.numRecord = value;
}
private DateTime SelDtRef
{
get => SelFilter.DtRef;
}
private string SelMacchina
{
get => SelFilter.IdxMacchina;
}
private int totalCount
{
get => _totalCount;
set
{
if (_totalCount != value)
{
_totalCount = value;
TotRecordChanged.InvokeAsync(value);
}
}
}
private bool visualizzaFlux { get; set; } = true;
#endregion Private Properties
#region Private Methods
private async void MessageService_EA_PageUpdated()
{
await reloadData();
}
private async Task reloadData()
{
isLoading = true;
SearchRecords = await MDService.DossiersGetLastFilt(SelMacchina, SelDtRef, MaxRecord);
totalCount = SearchRecords.Count;
ListRecords = SearchRecords.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList();
await Task.Delay(1);
await InvokeAsync(() => StateHasChanged());
isLoading = false;
}
private async Task toggleTableFlux()
{
visualizzaFlux = false;
await Task.Delay(1);
}
private async Task unToggleTableFlux()
{
currRecord = null;
visualizzaFlux = true;
await Task.Delay(1);
}
#endregion Private Methods
}
}
+68
View File
@@ -0,0 +1,68 @@
@using MP.SPEC.Components
@using MP.SPEC.Data
@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">
<thead>
<tr>
<th>
@*<button @onclick="() => resetSel()" class="btn btn-primary btn-sm"><i class="bi bi-arrow-counterclockwise"></i></button>*@
</th>
<th><i class="fa-solid fa-file"></i> Articolo</th>
<th><i class="fa-solid fa-hard-drive"></i> Macchina</th>
<th># pz</th>
<th><i class="fa-solid fa-clock"></i> T.Ciclo</th>
<th><i class="fa-solid fa-play"></i> Inizio</th>
<th><i class="fa-solid fa-pen-to-square"></i> Note</th>
<th><i class="fa-solid fa-code-pull-request"></i> Richiesta</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var record in ListRecords)
{
<tr class="@checkSelect(@record.CodArticolo)">
<td>
@*<button @onclick="() => selRecord(record)" class="btn btn-primary btn-sm"><i class="bi bi-pencil-square"></i></button>*@
</td>
<td>
@record.CodArticolo
</td>
<td>
@record.IdxMacchina
</td>
<td>
@record.NumPezzi
</td>
<td>
@record.Tcassegnato.ToString("N3")
</td>
<td>
<div>@record.DataInizio</div>
</td>
<td>@record.Note</td>
<td>@record.KeyRichiesta</td>
<td>
@*@if (ArticoloDelEnabled(record.CodArticolo))
{
<button @onclick="() => deleteRecord(record)" class="btn btn-danger btn-sm"><i class="bi bi-trash-fill"></i></button>
}*@
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
}
+153
View File
@@ -0,0 +1,153 @@
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using MP.Data.DatabaseModels;
using MP.SPEC.Data;
namespace MP.SPEC.Components
{
public partial class ListODL
{
#region Public Properties
[Parameter]
public EventCallback<bool> PagerResetReq { get; set; }
[Parameter]
public string StatoSel
{
get => _statoSel;
set
{
if (_statoSel != value)
{
_statoSel = value;
var pUpd = Task.Run(async () => await reloadData());
pUpd.Wait();
}
}
}
#endregion Public Properties
#region Public Methods
public string checkSelect(string CodArticolo)
{
string answ = "";
if (currRecord != null)
{
try
{
answ = (currRecord.CodArticolo == CodArticolo) ? "table-info" : "";
}
catch
{ }
}
return answ;
}
#endregion Public Methods
#region Protected Properties
[Inject]
protected IJSRuntime JSRuntime { get; set; } = null!;
[Inject]
protected MpDataService MDService { get; set; } = null!;
[Inject]
protected MessageService MessageService { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected override async Task OnInitializedAsync()
{
MessageService.EA_PageUpdated += MessageService_EA_PageUpdated;
MessageService.EA_SearchUpdated += OnSeachUpdated;
await reloadData();
}
protected async void OnSeachUpdated()
{
await InvokeAsync(() =>
{
PagerResetReq.InvokeAsync(true);
//currPage = 1;
Task task = UpdateData();
StateHasChanged();
});
}
protected async Task UpdateData()
{
currRecord = null;
await reloadData();
}
#endregion Protected Methods
#region Private Fields
private string _statoSel = "*";
private ODLModel? currRecord = null;
private List<ODLModel>? ListRecords;
private List<ODLModel>? SearchRecords;
#endregion Private Fields
#region Private Properties
private int currPage
{
get => MessageService.currPage;
set => MessageService.currPage = value;
}
private bool isLoading { get; set; } = false;
private int numRecord
{
get => MessageService.numRecord;
set => MessageService.numRecord = value;
}
private string SearchVal
{
get => string.IsNullOrEmpty(MessageService.SearchVal) ? "*" : MessageService.SearchVal;
}
private int totalCount
{
get => MessageService.totalCount;
set => MessageService.totalCount = value;
}
#endregion Private Properties
#region Private Methods
private async void MessageService_EA_PageUpdated()
{
await reloadData();
}
private async Task reloadData()
{
isLoading = true;
SearchRecords = await MDService.ListODLFilt(true, SearchVal, StatoSel);
totalCount = SearchRecords.Count;
ListRecords = SearchRecords.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList();
await Task.Delay(1);
await InvokeAsync(() => StateHasChanged());
isLoading = false;
}
#endregion Private Methods
}
}
+62
View File
@@ -0,0 +1,62 @@
@using MP.SPEC.Components
@using MP.SPEC.Data
@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 small">
<thead>
<tr>
<th>
@*<button @onclick="() => resetSel()" class="btn btn-primary btn-sm"><i class="bi bi-arrow-counterclockwise"></i></button>*@
</th>
<th><i class="fa-regular fa-calendar-days"></i> Data</th>
<th><i class="fa-solid fa-hard-drive"></i> Macchina</th>
<th><i class="fa-solid fa-sliders"></i> Parametro</th>
<th style="text-align: right">Valore</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var record in ListRecords)
{
<tr class="@checkSelect(@record.IdxMacchina)">
<td>
@*<button @onclick="() => selRecord(record)" class="btn btn-primary btn-sm"><i class="bi bi-pencil-square"></i></button>*@
</td>
<td>
@record.dtEvento
</td>
<td>
@record.IdxMacchina
</td>
<td>
@record.CodFlux
</td>
<td style="text-align: right">
<b>@record.Valore</b>
</td>
<td>
@*@if (ArticoloDelEnabled(record.CodArticolo))
{
<button @onclick="() => deleteRecord(record)" class="btn btn-danger btn-sm"><i class="bi bi-trash-fill"></i></button>
}*@
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
}
+219
View File
@@ -0,0 +1,219 @@
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using MP.Data.DatabaseModels;
using MP.SPEC.Data;
using System.Diagnostics;
namespace MP.SPEC.Components
{
public partial class ListPARAMS : IDisposable
{
#region Public Properties
[Parameter]
public EventCallback<bool> PagerResetReq { get; set; }
[Parameter]
public SelectFluxParams SelFilter { get; set; } = null!;
[Parameter]
public EventCallback<int> TotRecordChanged { get; set; }
#endregion Public Properties
#region Public Methods
public string checkSelect(string IdxMacchina)
{
string answ = "";
if (currRecord != null)
{
try
{
answ = (currRecord.IdxMacchina == IdxMacchina) ? "table-info" : "";
}
catch
{ }
}
return answ;
}
public void Dispose()
{
aTimer.Elapsed -= ElapsedTimer;
MessageService.EA_PageUpdated -= MessageService_EA_PageUpdated;
MessageService.EA_SearchUpdated -= OnSeachUpdated;
aTimer.Stop();
aTimer.Dispose();
}
public void ElapsedTimer(object? source, System.Timers.ElapsedEventArgs e)
{
if (!isLoading && LiveUpdate)
{
aTimer.Stop();
// inizio misura esecuzione
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
var pUpd = Task.Run(async () =>
{
await Task.Delay(1);
await InvokeAsync(() => reloadData(true));
});
pUpd.Wait();
// misuro tempo esecuzione
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
int deltaTime = RefreshPeriod - (int)ts.TotalMilliseconds;
aTimer.Interval = deltaTime > 100 ? deltaTime : 100;
aTimer.Start();
}
}
public async Task reloadData(bool setChanged)
{
isLoading = true;
SearchRecords = await MDService.FluxLogGetLastFilt(SelMacchina, SelFlux, MaxRecord);
totalCount = SearchRecords.Count;
ListRecords = SearchRecords.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList();
await Task.Delay(1);
if (setChanged)
{
await InvokeAsync(() => StateHasChanged());
}
isLoading = false;
}
public void StartTimer()
{
//int.TryParse(Configuration["ReloadStatusTimer"], out tOutPeriod);
aTimer = new System.Timers.Timer(RefreshPeriod);
aTimer.Elapsed += ElapsedTimer;
aTimer.Enabled = true;
//aTimer.AutoReset = true;
aTimer.Start();
}
#endregion Public Methods
#region Protected Properties
[Inject]
protected IJSRuntime JSRuntime { get; set; } = null!;
[Inject]
protected MpDataService MDService { get; set; } = null!;
[Inject]
protected MessageService MessageService { get; set; } = null!;
protected int RefreshPeriod
{
get => SelFilter.TempoAgg;
}
//protected int RefreshPeriod { get; set; } = 5000;
#endregion Protected Properties
#region Protected Methods
protected override async Task OnInitializedAsync()
{
MessageService.EA_PageUpdated += MessageService_EA_PageUpdated;
MessageService.EA_SearchUpdated += OnSeachUpdated;
StartTimer();
await reloadData(true);
}
protected async void OnSeachUpdated()
{
await InvokeAsync(() =>
{
PagerResetReq.InvokeAsync(false);
//currPage = 1;
Task task = UpdateData();
StateHasChanged();
});
}
protected async Task UpdateData()
{
currRecord = null;
await reloadData(true);
}
#endregion Protected Methods
#region Private Fields
private static System.Timers.Timer aTimer = null!;
private int _totalCount = 0;
private FluxLog? currRecord = null;
private List<FluxLog>? ListRecords;
private List<FluxLog>? SearchRecords;
#endregion Private Fields
#region Private Properties
private int currPage
{
get => MessageService.currPage;
set => MessageService.currPage = value;
}
private bool isLoading { get; set; } = false;
private bool LiveUpdate
{
get => SelFilter.LiveUpdate;
}
private int MaxRecord
{
get => SelFilter.MaxRecord;
}
private int numRecord
{
get => MessageService.numRecord;
set => MessageService.numRecord = value;
}
private string SelFlux
{
get => SelFilter.CodFlux;
}
private string SelMacchina
{
get => SelFilter.IdxMacchina;
}
private int totalCount
{
get => _totalCount;
set
{
if (_totalCount != value)
{
_totalCount = value;
TotRecordChanged.InvokeAsync(value);
}
}
}
#endregion Private Properties
#region Private Methods
private async void MessageService_EA_PageUpdated()
{
await reloadData(true);
}
#endregion Private Methods
}
}
+65
View File
@@ -0,0 +1,65 @@
@using MP.SPEC.Components
@using MP.SPEC.Data
@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">
<thead>
<tr>
<th>
<button @onclick="() => resetSel()" class="btn btn-primary btn-sm"><i class="bi bi-arrow-counterclockwise"></i></button>
</th>
<th><i class="fa-solid fa-file"></i> Articolo</th>
<th><i class="fa-solid fa-screwdriver-wrench"></i> Fase</th>
<th><i class="fa-solid fa-hard-drive"></i> Macchina</th>
<th># pz</th>
<th><i class="fa-solid fa-clock"></i> T.Ciclo</th>
<th><i class="fa-solid fa-pen-to-square"></i> Note</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var record in ListRecords)
{
<tr class="@checkSelect(@record.CodArticolo)">
<td>
<button @onclick="() => selRecord(record)" class="btn btn-primary btn-sm"><i class="bi bi-pencil-square"></i></button>
</td>
<td>
@record.CodArticolo
</td>
<td>@tradFase(record.KeyRichiesta)</td>
<td>
@record.IdxMacchina
</td>
<td>
@record.NumPezzi
</td>
<td>
@record.Tcassegnato.ToString("N3")
</td>
<td>@record.Note</td>
<td>
@if (POdlDelEnabled(record.IdxOdl))
{
<button @onclick="() => deleteRecord(record)" class="btn btn-danger btn-sm"><i class="bi bi-trash-fill"></i></button>
}
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
}
+208
View File
@@ -0,0 +1,208 @@
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using MP.Data.DatabaseModels;
using MP.SPEC.Data;
namespace MP.SPEC.Components
{
public partial class ListPODL
{
#region Public Properties
[Parameter]
public EventCallback<bool> PagerResetReq { get; set; }
[Parameter]
public EventCallback<PODLModel> RecordSel { get; set; }
#endregion Public Properties
#region Public Methods
public string checkSelect(string CodArticolo)
{
string answ = "";
if (currRecord != null)
{
try
{
answ = (currRecord.CodArticolo == CodArticolo) ? "table-info" : "";
}
catch
{ }
}
return answ;
}
protected async Task resetSel()
{
await RecordSel.InvokeAsync(null);
}
protected bool POdlDelEnabled(int idxOdl)
{
return idxOdl == 0;
}
protected async Task selRecord(PODLModel selRec)
{
await RecordSel.InvokeAsync(selRec);
}
/// <summary>
/// Eliminazione record selezioanto (previa conferma)
/// </summary>
/// <param name="selRec"></param>
/// <returns></returns>
protected async Task deleteRecord(PODLModel selRec)
{
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Eliminazione Record: sei sicuro di voler procedere?"))
return;
await Task.Delay(1);
var done = await MDService.PODLDeleteRecord(selRec);
currRecord = null;
await reloadData();
await Task.Delay(1);
}
#endregion Public Methods
#region Protected Properties
[Inject]
protected IJSRuntime JSRuntime { get; set; } = null!;
[Inject]
protected MpDataService MDService { get; set; } = null!;
[Inject]
protected MessageService MsgService { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected override async Task OnInitializedAsync()
{
MsgService.EA_PageUpdated += MessageService_EA_PageUpdated;
MsgService.EA_SearchUpdated += OnSeachUpdated;
MsgService.EA_StatoSearch += MsgService_EA_StatoSearch;
ListStati = await MDService.AnagStatiComm();
await reloadData();
}
protected async void OnSeachUpdated()
{
await InvokeAsync(() =>
{
PagerResetReq.InvokeAsync(true);
//currPage = 1;
Task task = UpdateData();
StateHasChanged();
});
}
protected async Task UpdateData()
{
currRecord = null;
await reloadData();
}
#endregion Protected Methods
#region Private Fields
private PODLModel? currRecord = null;
private List<PODLModel>? ListRecords;
private List<PODLModel>? SearchRecords;
#endregion Private Fields
#region Private Properties
private int currPage
{
get => MsgService.currPage;
set => MsgService.currPage = value;
}
private bool isLoading { get; set; } = false;
private int numRecord
{
get => MsgService.numRecord;
set => MsgService.numRecord = value;
}
private string SearchVal
{
get => string.IsNullOrEmpty(MsgService.SearchVal) ? "*" : MsgService.SearchVal;
}
private string StatoSel
{
get => MsgService.StateSel;
set => MsgService.StateSel = value;
}
private int totalCount
{
get => MsgService.totalCount;
set => MsgService.totalCount = value;
}
#endregion Private Properties
#region Private Methods
private async void MessageService_EA_PageUpdated()
{
await reloadData();
}
private async void MsgService_EA_StatoSearch()
{
await InvokeAsync(() =>
{
PagerResetReq.InvokeAsync(true);
//currPage = 1;
Task task = UpdateData();
StateHasChanged();
});
}
private string tradFase(string codFase)
{
string answ = codFase;
if (ListStati != null && ListStati.Count > 0)
{
var recSel = ListStati.FirstOrDefault(x => x.value == codFase);
if (recSel != null)
{
answ = recSel.label;
}
}
return answ;
}
private List<ListValues>? ListStati;
private async Task reloadData()
{
isLoading = true;
SearchRecords = await MDService.ListPODLFilt(SearchVal, StatoSel);
totalCount = SearchRecords.Count;
ListRecords = SearchRecords.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList();
await Task.Delay(1);
await InvokeAsync(() => StateHasChanged());
isLoading = false;
}
#endregion Private Methods
}
}
+10
View File
@@ -0,0 +1,10 @@
<div class="row p-5 m-5 alert alert-primary">
<div class="col-6 text-center mt-4 py-3 bg-light">
<h1>MAPO SPEC</h1>
EgalWare MES suite <img class="logoImg img-fluid" src="images/logoCliente.png" width="64" />
</div>
<div class="col-6 text-center mt-4 py-3 bg-light">
<h3>loading data</h3>
<i class="fas fa-spinner fa-spin fa-4x"></i>
</div>
</div>
@@ -0,0 +1,6 @@
<div class="row p-0 m-0">
<div class="col-12 text-center py-2 mb-0 alert alert-primary">
<b>loading data</b>
<i class="fas fa-spinner fa-spin"></i>
</div>
</div>
+112
View File
@@ -0,0 +1,112 @@
<div class="d-flex justify-content-between">
<div class="px-0 py-1">
<div class="d-flex justify-content-between">
<div class="px-2">
@if (!liveUpdate)
{
<button class="btn btn-secondary" type="button" @onclick="() => toggleUpdate()">
<small>@lastUpdate</small>
</button>
}
else
{
<button class="btn btn-primary" type="button" @onclick="() => toggleUpdate()">
<span class="spinner-grow spinner-grow-sm" role="status" aria-hidden="true"></span>
Valori live
</button>
}
</div>
<div class="px-2">
@if (selMacchina != "*")
{
<button class="btn btn-warning" type="button" @onclick="() => takeSnapshot()">
<i class="fa-solid fa-camera"></i>
Registra
</button>
}
</div>
</div>
</div>
<div class="px-0">
<div class="d-flex justify-content-end">
@if (showEditPar)
{
<div class="px-0 input-group py-1" id="basic-addon1">
<button class="btn btn-primary" @onclick="() => toggleParams()"> <i class="fa-solid fa-arrow-right"></i></button>
<label class="input-group-text" for="tempoAgg" title="Selezionare il tempo di aggiornamento dei dati"><i class="fa-solid fa-clock"></i></label>
<select @bind="@selTempoAgg" class="form-select" id="tempoAgg" title="Selezionare il tempo di aggiornamento dei dati" style="width: 3em;">
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
<option value="9">9</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
<option value="13">13</option>
<option value="14">14</option>
<option value="15">15</option>
<option value="16">16</option>
<option value="17">17</option>
<option value="18">18</option>
<option value="19">19</option>
<option value="20">20</option>
</select>
<label class="input-group-text" for="maxRecord" title="Selezionare il numero massimo di record da visualizzare"><i class="fa-solid fa-list-ol"></i></label>
<select @bind="@selMaxRecord" class="form-select" id="maxRecord" title="Selezionare il numero massimo di record da visualizzare">
<option value="50">50</option>
<option value="100">100</option>
<option value="150">150</option>
<option value="200">200</option>
<option value="250">250</option>
<option value="300">300</option>
<option value="350">350</option>
<option value="400">400</option>
<option value="450">450</option>
<option value="500">500</option>
</select>
</div>
}
else
{
<div class="px-2 py-1">
<button class="btn btn-primary" @onclick="() => toggleParams()"><i class="fa-solid fa-arrow-left"></i></button>
</div>
}
<div class="px-0 py-1">
<div class="px-2 input-group" id="basic-addon1">
<label class="input-group-text" for="macchina" title="Selezionare la macchina"><i class="fa-solid fa-hard-drive"></i></label>
<select @bind="@selMacchina" class="form-select" id="macchina" title="Selezionare la macchina">
<option value="*">--- Tutti ---</option>
@if (ListMacchine != null)
{
foreach (var item in ListMacchine)
{
<option value="@item">@item</option>
}
}
</select>
<label class="input-group-text" for="flusso" title="Selezionare il tipo di flusso"><i class="fa-solid fa-sliders"></i></label>
<select @bind="@selFlux" class="form-select" id="flusso" title="Selezionare il tipo di flusso">
<option value="*">--- Tutti ---</option>
@if (ListFlux != null)
{
foreach (var item in ListFlux)
{
<option value="@item">@item</option>
}
}
</select>
</div>
</div>
</div>
</div>
</div>
+184
View File
@@ -0,0 +1,184 @@
using Microsoft.AspNetCore.Components;
using MP.SPEC.Data;
namespace MP.SPEC.Components
{
public partial class ParamsFilter
{
#region Public Properties
[Parameter]
public EventCallback<SelectFluxParams> FilterChanged { get; set; }
[Parameter]
public SelectFluxParams SelFilter { get; set; } = null!;
#endregion Public Properties
#region Protected Fields
protected string lastUpdate
{
get => SelFilter.lastUpdate;
set => SelFilter.lastUpdate = value;
}
#endregion Protected Fields
#region Protected Properties
protected bool liveUpdate
{
get => SelFilter.LiveUpdate;
set
{
if (!SelFilter.LiveUpdate.Equals(value))
{
SelFilter.LiveUpdate = value;
if (!value)
{
SelFilter.CurrPage = 0;
}
reportChange();
}
}
}
[Inject]
protected MpDataService MDService { get; set; } = null!;
protected string selFlux
{
get
{
return SelFilter.CodFlux;
}
set
{
if (!SelFilter.CodFlux.Equals(value))
{
SelFilter.CurrPage = 1;
SelFilter.CodFlux = value;
StateHasChanged();
Task.Delay(1);
reportChange();
}
}
}
protected string selMacchina
{
get
{
return SelFilter.IdxMacchina;
}
set
{
if (!SelFilter.IdxMacchina.Equals(value))
{
SelFilter.CurrPage = 1;
SelFilter.IdxMacchina = value;
SelFilter.CodFlux = "*";
ListFlux = MDService.ParametriGetFilt(selMacchina).Result;
StateHasChanged();
Task.Delay(1);
reportChange();
}
}
}
protected int selMaxRecord
{
get
{
return SelFilter.MaxRecord;
}
set
{
if (!SelFilter.MaxRecord.Equals(value))
{
SelFilter.MaxRecord = value;
reportChange();
}
}
}
protected int selTempoAgg
{
get
{
return SelFilter.TempoAgg / 1000;
}
set
{
int tempoMS = value * 1000;
if (!SelFilter.TempoAgg.Equals(tempoMS))
{
SelFilter.TempoAgg = tempoMS;
reportChange();
}
}
}
#endregion Protected Properties
#region Protected Methods
protected override async Task OnInitializedAsync()
{
SelFilter = new SelectFluxParams();
ListMacchine = await MDService.MacchineWithFlux();
ListFlux = await MDService.ParametriGetFilt(selMacchina);
await FilterChanged.InvokeAsync(SelFilter);
}
protected void toggleParams()
{
showEditPar = !showEditPar;
}
protected async Task toggleUpdate()
{
liveUpdate = !liveUpdate;
await Task.Delay(1);
if (!liveUpdate)
{
lastUpdate = $"Last Snapshot: {DateTime.Now:yyyy/MM/dd HH:mm:ss}";
}
}
protected async Task takeSnapshot()
{
// fermo udpate
liveUpdate = false;
await MDService.DossiersTakeParamsSnapshot(selMacchina, 10);
lastUpdate = $"Last Snapshot: {DateTime.Now:yyyy/MM/dd HH:mm:ss}";
}
#endregion Protected Methods
#region Private Fields
private List<string>? ListFlux = null;
private List<string>? ListMacchine = null;
#endregion Private Fields
#region Private Properties
private bool showEditPar { get; set; } = false;
#endregion Private Properties
#region Private Methods
private void reportChange()
{
FilterChanged.InvokeAsync(SelFilter);
}
#endregion Private Methods
}
}
+55
View File
@@ -0,0 +1,55 @@
@using MP.SPEC.Components
@using MP.SPEC.Data
@inject MessageService AppMService
<div class="input-group input-group-sm" hidden>
<input @bind-value="@searchVal" @bind-value:event="oninput" type="text" class="form-control" title="Campo Ricerca" placeholder="Ricerca [ALT-R]" accesskey="R" />
<button @onclick="reset" class="btn btn-success input-group-text"><i class="fa-solid fa-rotate"></i></button>
</div>
@code {
[Parameter]
public EventCallback<string> searchUpdated { get; set; }
[Parameter]
public string searchVal
{
get
{
return AppMService.SearchVal;
}
set
{
AppMService.SearchVal = value;
reportChange();
}
}
protected override Task OnInitializedAsync()
{
AppMService.EA_SearchUpdated += OnSeachUpdated;
return base.OnInitializedAsync();
}
public async void OnSeachUpdated()
{
await InvokeAsync(() =>
{
StateHasChanged();
});
}
private void reportChange()
{
searchUpdated.InvokeAsync(searchVal);
}
private void reset()
{
searchVal = "";
}
}
+166
View File
@@ -0,0 +1,166 @@
namespace MP.SPEC.Data
{
public class MessageService
{
#region Public Events
public event Action EA_PageUpdated;
public event Action EA_SearchUpdated;
public event Action EA_ShowSearch;
public event Action EA_StatoSearch;
#endregion Public Events
#region Public Properties
public int currPage
{
get => _currPage;
set
{
if (_currPage != value)
{
_currPage = value;
if (EA_PageUpdated != null)
{
EA_PageUpdated?.Invoke();
}
}
}
}
public int numRecord
{
get => _numRecord;
set
{
if (_numRecord != value)
{
_numRecord = value;
if (EA_PageUpdated != null)
{
EA_PageUpdated?.Invoke();
}
}
}
}
public string SearchVal
{
get => searchVal;
set
{
//if (searchVal != value)
//{
searchVal = value;
if (EA_SearchUpdated != null)
{
EA_SearchUpdated?.Invoke();
}
//}
}
}
public bool ShowSearch
{
get => showSearch;
set
{
if (showSearch != value)
{
showSearch = value;
if (EA_ShowSearch != null)
{
EA_ShowSearch?.Invoke();
}
}
}
}
public string StateSel
{
get => stateSel;
set
{
stateSel = value;
if (EA_StatoSearch != null)
{
EA_StatoSearch?.Invoke();
}
}
}
public string TipoSearch
{
get => tipoSearch;
set
{
if (tipoSearch != value)
{
tipoSearch = value;
if (EA_ShowSearch != null)
{
EA_ShowSearch?.Invoke();
}
}
}
}
public int totalCount
{
get => _totalCount;
set
{
if (_totalCount != value)
{
_totalCount = value;
}
}
}
#endregion Public Properties
#region Protected Methods
protected void reportPaging()
{
if (EA_PageUpdated != null)
{
EA_PageUpdated?.Invoke();
}
}
protected void reportSearch()
{
if (EA_SearchUpdated != null)
{
EA_SearchUpdated?.Invoke();
}
}
#endregion Protected Methods
#region Private Fields
private string searchVal = "";
private bool showSearch;
private string stateSel = "*";
private string tipoSearch = "";
#endregion Private Fields
#region Private Properties
private int _currPage { get; set; } = 1;
private int _numRecord { get; set; } = 10;
private int _totalCount { get; set; } = 0;
#endregion Private Properties
}
}
+644
View File
@@ -0,0 +1,644 @@
using MP.Data;
using MP.Data.Conf;
using MP.Data.DatabaseModels;
using MP.Data.DTO;
using Newtonsoft.Json;
using NLog;
using StackExchange.Redis;
using System.Diagnostics;
namespace MP.SPEC.Data
{
public class MpDataService : IDisposable
{
#region Public Constructors
public MpDataService(IConfiguration configuration, ILogger<MpDataService> logger)
{
_logger = logger;
_logger.LogInformation("Starting MpDataService INIT");
_configuration = configuration;
// setup compoenti REDIS
redisConn = ConnectionMultiplexer.Connect(_configuration.GetConnectionString("Redis"));
redisConnAdmin = ConnectionMultiplexer.Connect(_configuration.GetConnectionString("RedisAdmin"));
redisDb = redisConn.GetDatabase();
// leggo cache lungo periodo
int.TryParse(_configuration.GetValue<string>("ServerConf:redisLongTimeCache"), out redisLongTimeCache);
_logger.LogInformation("Redis INIT");
// setup canali pub/sub
dataPipe = new MessagePipe(redisConn, Constants.ACT_MSE_DATA_KEY);
blinkPipe = new MessagePipe(redisConn, Constants.ACT_BLINK_KEY);
// conf DB
string connStr = _configuration.GetConnectionString("Mp.Data");
if (string.IsNullOrEmpty(connStr))
{
_logger.LogError("DbController: ConnString empty!");
}
else
{
dbController = new MP.Data.Controllers.MpSpecController(configuration);
_logger.LogInformation("DbController OK");
}
}
#endregion Public Constructors
#region Public Properties
public static MP.Data.Controllers.MpSpecController dbController { get; set; } = null!;
public MessagePipe blinkPipe { get; set; } = null!;
/// <summary>
/// Dizionario dei tag configurati per IOB
/// </summary>
public Dictionary<string, List<TagData>> currTagConf { get; set; } = new Dictionary<string, List<TagData>>();
public MessagePipe dataPipe { get; set; } = null!;
#endregion Public Properties
#region Public Methods
public async Task<List<ListValues>> AnagStatiComm()
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
List<ListValues>? result = new List<ListValues>();
// cerco in redis...
RedisValue rawData = await redisDb.StringGetAsync(redisStatoCom);
if (!string.IsNullOrEmpty($"{rawData}"))
{
result = JsonConvert.DeserializeObject<List<ListValues>>($"{rawData}");
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Debug($"AnagStatiComm Read from REDIS: {ts.TotalMilliseconds}ms");
}
else
{
result = await Task.FromResult(dbController.AnagStatiComm());
// serializzp e salvo...
rawData = JsonConvert.SerializeObject(result);
await redisDb.StringSetAsync(redisStatoCom, rawData, getRandTOut(redisLongTimeCache));
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Debug($"AnagStatiComm Read from DB: {ts.TotalMilliseconds}ms");
}
if (result == null)
{
result = new List<ListValues>();
}
return result;
}
public async Task<List<ListValues>> AnagTipoArtLV()
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
List<ListValues>? result = new List<ListValues>();
// cerco in redis...
RedisValue rawData = await redisDb.StringGetAsync(redisTipoArt);
if (!string.IsNullOrEmpty($"{rawData}"))
{
result = JsonConvert.DeserializeObject<List<ListValues>>($"{rawData}");
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Debug($"AnagTipoArtLV Read from REDIS: {ts.TotalMilliseconds}ms");
}
else
{
result = await Task.FromResult(dbController.AnagTipoArtLV());
// serializzp e salvo...
rawData = JsonConvert.SerializeObject(result);
await redisDb.StringSetAsync(redisTipoArt, rawData, getRandTOut(redisLongTimeCache));
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Debug($"AnagTipoArtLV Read from DB: {ts.TotalMilliseconds}ms");
}
if (result == null)
{
result = new List<ListValues>();
}
return result;
}
/// <summary>
/// Eliminazione record selezionato
/// </summary>
/// <param name="currRec"></param>
/// <returns></returns>
public async Task<bool> ArticoliDeleteRecord(AnagArticoli currRec)
{
return await dbController.ArticoliDeleteRecord(currRec);
}
/// <summary>
/// Restitusice elenco articoli cercati
/// </summary>
/// <param name="numRecord"></param>
/// <param name="searchVal"></param>
/// <returns></returns>
public async Task<List<AnagArticoli>> ArticoliGetSearch(int numRecord, string azienda, string searchVal)
{
return await Task.FromResult(dbController.ArticoliGetSearch(numRecord, azienda, searchVal));
}
/// <summary>
/// Aggiornamento record selezionato
/// </summary>
/// <param name="currRec"></param>
/// <returns></returns>
public async Task<bool> ArticoliUpdateRecord(AnagArticoli currRec)
{
return await dbController.ArticoliUpdateRecord(currRec);
}
/// <summary>
/// Verifica se sia possiubile cancellare articolo dato suo CodArt cercando su redis o su
/// tab veto da DB
/// </summary>
/// <param name="CodArt"></param>
/// <returns></returns>
public bool ArticoloDelEnabled(object CodArt)
{
bool answ = false;
string codArticolo = $"{CodArt}";
int cacheCheckArtUsato = 1;
int.TryParse(_configuration.GetValue<string>("ServerConf:cacheCheckArtUsato"), out cacheCheckArtUsato);
TimeSpan TTLCache = getRandTOut(cacheCheckArtUsato);
// cerco in cache redis...
string redKeyArtUsed = $"{Utils.redKeyArtUsed}:{codArticolo}";
string redKeyTabCheckArt = Utils.redKeyTabCheckArt;
string rawData = redisDb.StringGet(redKeyArtUsed);
if (!string.IsNullOrEmpty(rawData))
{
bool.TryParse(rawData, out answ);
}
else
{
// controllo non sia stato mai prodotto sennò non posso cancellare...
try
{
// cerco in cache se ci sia la tabella con gli articoli impiegati...
string rawTable = redisDb.StringGet(redKeyTabCheckArt);
List<string> artList = new List<string>();
if (!string.IsNullOrEmpty(rawTable))
{
artList = JsonConvert.DeserializeObject<List<string>>(rawTable);
}
// rileggo...
if (artList == null || artList.Count == 0)
{
artList = new List<string>();
var tabArticoli = dbController.ArticoliGetUsed();
var codList = tabArticoli.Select(x => x.CodArticolo);
foreach (string cod in codList)
{
artList.Add(cod);
}
// SE fosse vuoto aggiungo comunque il cado "ND"...
if (artList.Count == 0)
{
artList.Add("ND");
}
// salvo
rawTable = JsonConvert.SerializeObject(artList);
redisDb.StringSet(redKeyTabCheckArt, rawTable, TTLCache);
}
// cerco nella tabella: se ci fosse --> disabilitato delete
bool usato = false;
if (artList != null && artList.Count > 0)
{
usato = artList.Contains(codArticolo);
}
answ = !usato;
redisDb.StringSet(redKeyArtUsed, $"{answ}", TTLCache);
}
catch
{ }
}
return answ;
}
public async Task<List<ConfigModel>> ConfigGetAll()
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
List<ConfigModel>? result = new List<ConfigModel>();
// cerco in redis...
RedisValue rawData = await redisDb.StringGetAsync(redisConfKey);
if (!string.IsNullOrEmpty($"{rawData}"))
{
result = JsonConvert.DeserializeObject<List<ConfigModel>>($"{rawData}");
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Debug($"ConfigGetAll Read from REDIS: {ts.TotalMilliseconds}ms");
}
else
{
result = await Task.FromResult(dbController.ConfigGetAll());
// serializzp e salvo...
rawData = JsonConvert.SerializeObject(result);
await redisDb.StringSetAsync(redisConfKey, rawData, getRandTOut(redisLongTimeCache));
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Debug($"ConfigGetAll Read from DB: {ts.TotalMilliseconds}ms");
}
if (result == null)
{
result = new List<ConfigModel>();
}
return result;
}
/// <summary>
/// Reset dati cache config
/// </summary>
/// <returns></returns>
public async Task ConfigResetCache()
{
await redisDb.StringSetAsync(redisConfKey, "");
}
/// <summary>
/// Update chiave config
/// </summary>
/// <returns></returns>
public async Task<bool> ConfigUpdate(ConfigModel updRec)
{
return await Task.FromResult(dbController.ConfigUpdate(updRec));
}
public List<FluxLog> convertToFluxLog(string Valore)
{
//string valStriped = Valore.Substring(7, Valore.Length - 8);
//var result = JsonConvert.DeserializeObject<List<FluxLog>>(valStriped);
var result = JsonConvert.DeserializeObject<DossierFluxLogDTO>(Valore);
return result.ODL;
}
public void Dispose()
{
// Clear database controller
dbController.Dispose();
redisConn.Dispose();
}
/// <summary>
/// Elenco ultimi n record DOssiers (che contengono ad esempio "salvataggi" di FLuxLog) dato
/// macchina (ordinato x data registrazione)
/// </summary>
/// <param name="IdxMacchina">* = tutte, altrimenti solo x una data macchina</param>
/// <param name="DtRef">Data di riferimento (Massima) per estrazione records</param>
/// <param name="MaxRec">numero massimo record da restituire</param>
/// <returns></returns>
public async Task<List<Dossiers>> DossiersGetLastFilt(string IdxMacchina, DateTime DtRef, int MaxRec)
{
List<Dossiers>? result = new List<Dossiers>();
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
string readType = "DB";
string currKey = $"{redisDossByMac}:{IdxMacchina}";
// cerco in redis dato valore sel macchina...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<List<Dossiers>>($"{rawData}");
readType = "REDIS";
}
else
{
result = await Task.FromResult(dbController.DossiersGetLastFilt(IdxMacchina, DtRef, MaxRec));
// serializzp e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache / 5));
}
if (result == null)
{
result = new List<Dossiers>();
}
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Debug($"DossiersGetLastFilt | Read from {readType}: {ts.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Effettua salvataggio snapshot parametri (con stored) + svuota eventuale cache redis
/// </summary>
/// <param name="IdxMacchina">macchina</param>
/// <param name="maxSec">NUm massimo secondi per recuperare dati correnti</param>
/// <returns></returns>
public async Task<bool> DossiersTakeParamsSnapshot(string IdxMacchina, int MaxSec)
{
bool answ = false;
await Task.Delay(1);
// chiamo stored x salvare parametri
dbController.DossiersTakeParamsSnapshot(IdxMacchina, MaxSec);
// svuoto cache redis x macchina
string currKey = $"{redisDossByMac}:{IdxMacchina}";
redisDb.StringSet(currKey, "", TimeSpan.FromSeconds(1));
currKey = $"{redisDossByMac}:*";
redisDb.StringSet(currKey, "", TimeSpan.FromSeconds(1));
return answ;
}
/// <summary>
/// Restitusice elenco aziende
/// </summary>
/// <returns></returns>
public Task<List<AnagGruppi>> ElencoAziende()
{
return Task.FromResult(dbController.AnagGruppiAziende());
}
/// <summary>
/// Restitusice elenco fasi
/// </summary>
/// <returns></returns>
public Task<List<AnagGruppi>> ElencoGruppiFase()
{
return Task.FromResult(dbController.AnagGruppiFase());
}
public Task<List<LinkMenu>> ElencoLink()
{
return Task.FromResult(dbController.ElencoLink());
}
public async Task<bool> FlushRedisCache()
{
await Task.Delay(1);
bool answ = false;
var listEndpoints = redisConnAdmin.GetEndPoints();
var server = redisConnAdmin.GetServer(listEndpoints[0]);
RedisValue pattern = new RedisValue($"{redisBaseAddr}*");
if (server != null)
{
var keyList = server.Keys(redisDb.Database, pattern);
foreach (var item in keyList)
{
await redisDb.KeyDeleteAsync(item);
}
// brutalmente rimuovo intero contenuto DB... DANGER
//await server.FlushDatabaseAsync();
answ = true;
}
return answ;
}
/// <summary>
/// Elenco ultimi n record flux log dato macchina e flusso (ordinato x data registrazione)
/// </summary>
/// <param name="IdxMacchina">* = tutte, altrimenti solo x una data macchina</param>
/// <param name="CodFlux">*=tutti, altrimenti solo selezionato</param>
/// <param name="MaxRec">numero massimo record da restituire</param>
/// <returns></returns>
public async Task<List<FluxLog>> FluxLogGetLastFilt(string IdxMacchina, string CodFlux, int MaxRec)
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
var results = await Task.FromResult(dbController.FluxLogGetLastFilt(IdxMacchina, CodFlux, MaxRec));
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Debug($"FluxLogGetLastFilt | Read from DB: {ts.TotalMilliseconds}ms");
return results;
}
/// <summary>
/// Elenco setup dei tag conf correnti
/// </summary>
/// <returns></returns>
public Task<Dictionary<string, List<TagData>>> getAllTags()
{
return Task.FromResult(currTagConf);
}
/// <summary>
/// restituisce il valore da REDIS associato al tag richeisto
/// </summary>
/// <param name="redKey">Chiave in cui cercare il valore</param>
/// <returns></returns>
public string getTagConf(string redKey)
{
string outVal = "";
// cerco in REDIS la conf x l'IOB
var rawData = redisDb.StringGet(redKey);
if (!string.IsNullOrEmpty(rawData))
{
outVal = $"{rawData}";
}
return outVal;
}
/// <summary>
/// Elenco ODL filtrati x stato, articolo, KeyRich (che contiene stato)
/// </summary>
/// <param name="inCorso">Stato ODL: true=in corso/completato</param>
/// <param name="codArt">Cod articolo</param>
/// <param name="keyRichPart">KeyRich (parziale) da cercare (es cod stato x yacht)</param>
/// <returns></returns>
public async Task<List<ODLModel>> ListODLFilt(bool inCorso, string codArt, string keyRichPart)
{
return await Task.FromResult(dbController.ListODLFilt(inCorso, codArt, keyRichPart));
}
/// <summary>
/// Elenco PODL non avviati filtrati x articolo, KeyRich (che contiene stato)
/// </summary>
/// <param name="codArt">Cod articolo</param>
/// <param name="keyRichPart">KeyRich (parziale) da cercare (es cod stato x yacht)</param>
/// <returns></returns>
public async Task<List<PODLModel>> ListPODLFilt(string codArt, string keyRichPart)
{
return await Task.FromResult(dbController.ListPODLFilt(codArt, keyRichPart));
}
/// <summary>
/// Elenco di tutte le macchine gestite
/// </summary>
/// <returns></returns>
public async Task<List<Macchine>> MacchineGetAll()
{
List<Macchine>? result = new List<Macchine>();
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
string readType = "DB";
string currKey = redisMacList;
// cerco in redis dato valore sel macchina...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<List<Macchine>>($"{rawData}");
readType = "REDIS";
}
else
{
result = await Task.FromResult(dbController.MacchineGetAll());
// serializzp e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache));
}
if (result == null)
{
result = new List<Macchine>();
}
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Debug($"MacchineGetAll | Read from {readType}: {ts.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Elenco ID macchine con dati FluxLog gestite
/// </summary>
/// <returns></returns>
public async Task<List<string>> MacchineWithFlux()
{
List<string>? result = new List<string>();
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
string readType = "DB";
string currKey = redisMacByFlux;
// cerco in redis dato valore sel macchina...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<List<string>>($"{rawData}");
readType = "REDIS";
}
else
{
result = await Task.FromResult(dbController.MacchineWithFlux());
// serializzp e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache));
}
if (result == null)
{
result = new List<string>();
}
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Debug($"MacchineWithFlux | Read from {readType}: {ts.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Elenco di tutti i parametri filtrati x macchina
/// </summary>
/// <param name="IdxMacchina">* = tutte, altrimenti solo x una data macchina</param>
/// <returns></returns>
public async Task<List<string>> ParametriGetFilt(string IdxMacchina)
{
List<string>? result = new List<string>();
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
string readType = "DB";
string currKey = $"{redisFluxByMac}:{IdxMacchina}";
// cerco in redis dato valore sel macchina...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<List<string>>($"{rawData}");
readType = "REDIS";
}
else
{
result = await Task.FromResult(dbController.ParametriGetFilt(IdxMacchina));
// serializzp e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache));
}
if (result == null)
{
result = new List<string>();
}
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Debug($"ParametriGetFilt | Read from {readType}: {ts.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Eliminazione record selezionato
/// </summary>
/// <param name="currRec"></param>
/// <returns></returns>
public async Task<bool> PODLDeleteRecord(PODLModel currRec)
{
return await dbController.PODLDeleteRecord(currRec);
}
/// <summary>
/// Aggiornamento record selezionato
/// </summary>
/// <param name="currRec"></param>
/// <returns></returns>
public async Task<bool> POdlUpdateRecord(PODLModel currRec)
{
return await dbController.PODLUpdateRecord(currRec);
}
#endregion Public Methods
#region Protected Fields
protected Random rand = new Random();
#endregion Protected Fields
#region Protected Methods
/// <summary>
/// Restituisce un timeout dai minuti richiesti + tempo random 1..60 sec
/// </summary>
/// <param name="stdMinutes"></param>
/// <returns></returns>
protected TimeSpan getRandTOut(int stdMinutes)
{
double rndValue = (double)stdMinutes + (double)rand.Next(1, 60) / 60;
return TimeSpan.FromMinutes(rndValue);
}
#endregion Protected Methods
#region Private Fields
private const string redisBaseAddr = "MP:";
private const string redisConfKey = redisBaseAddr + "SPEC:Cache:Config";
private const string redisDossByMac = redisBaseAddr + "SPEC:Cache:DossByMac";
private const string redisFluxByMac = redisBaseAddr + "SPEC:Cache:FluxByMac";
private const string redisMacByFlux = redisBaseAddr + "SPEC:Cache:MacByFlux";
private const string redisMacList = redisBaseAddr + "SPEC:Cache:MacList";
private const string redisStatoCom = redisBaseAddr + "SPEC:Cache:StatoCom";
private const string redisTipoArt = redisBaseAddr + "SPEC:Cache:TipoArt";
private static IConfiguration _configuration = null!;
private static ILogger<MpDataService> _logger = null!;
private static Logger Log = LogManager.GetCurrentClassLogger();
/// <summary>
/// Oggetto per connessione a REDIS
/// </summary>
private ConnectionMultiplexer redisConn = null!;
/// <summary>
/// Oggetto per connessione a REDIS modalità admin (ex flux dati)
/// </summary>
private ConnectionMultiplexer redisConnAdmin = null!;
/// <summary>
/// Oggetto DB redis da impiegare x chiamate R/W
/// </summary>
private IDatabase redisDb = null!;
private int redisLongTimeCache = 5;
#endregion Private Fields
}
}
+68
View File
@@ -0,0 +1,68 @@
namespace MP.SPEC.Data
{
public class SelectDossierParams
{
#region Public Constructors
public SelectDossierParams()
{ }
#endregion Public Constructors
#region Public Properties
/// <summary>
        /// Inizializzazione con periodo e arrotondamento
        /// </summary>
        /// <param name="minRound"></param>
        /// <param name="numDayPrev"></param>
        /// <returns></returns>
        public static DateTime Init(int minRound)
{
TimeSpan DayElapsed = DateTime.Now.Subtract(DateTime.Today);
int minDay = (int)Math.Ceiling((double)(DayElapsed.TotalMinutes / minRound)) * minRound;
DateTime endRounded = DateTime.Today.AddMinutes(minDay);
return endRounded;
}
public string IdxMacchina { get; set; } = "*";
public int MaxRecord { get; set; } = 100;
public DateTime DtRef { get; set; } = Init(5);
public int CurrPage { get; set; } = 1;
#endregion Public Properties
#region Public Methods
public override bool Equals(object obj)
{
if (!(obj is SelectDossierParams item))
return false;
if (IdxMacchina != item.IdxMacchina)
return false;
if (MaxRecord != item.MaxRecord)
return false;
if (DtRef != item.DtRef)
return false;
if (CurrPage != item.CurrPage)
return false;
//if (lastUpdate != item.lastUpdate)
// return false;
return true;
}
public override int GetHashCode()
{
return base.GetHashCode();
}
#endregion Public Methods
}
}
+63
View File
@@ -0,0 +1,63 @@
namespace MP.SPEC.Data
{
public class SelectFluxParams
{
#region Public Constructors
public SelectFluxParams()
{ }
#endregion Public Constructors
#region Public Properties
public string CodFlux { get; set; } = "*";
public string IdxMacchina { get; set; } = "*";
public bool LiveUpdate { get; set; } = true;
public int MaxRecord { get; set; } = 100;
public int TempoAgg { get; set; } = 2000;
public int CurrPage { get; set; } = 1;
public string lastUpdate { get; set; } = "-";
#endregion Public Properties
#region Public Methods
public override bool Equals(object obj)
{
if (!(obj is SelectFluxParams item))
return false;
if (IdxMacchina != item.IdxMacchina)
return false;
if (CodFlux != item.CodFlux)
return false;
if (LiveUpdate != item.LiveUpdate)
return false;
if (MaxRecord != item.MaxRecord)
return false;
if (TempoAgg != item.TempoAgg)
return false;
if (CurrPage != item.CurrPage)
return false;
if (lastUpdate != item.lastUpdate)
return false;
return true;
}
public override int GetHashCode()
{
return base.GetHashCode();
}
#endregion Public Methods
}
}
+50
View File
@@ -0,0 +1,50 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<RootNamespace>MP.SPEC</RootNamespace>
<Version>6.16.2209.2110</Version>
</PropertyGroup>
<ItemGroup>
<Content Remove="compilerconfig.json" />
</ItemGroup>
<ItemGroup>
<None Include="compilerconfig.json" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authentication.Negotiate" Version="6.0.6" />
<PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
</ItemGroup>
<ItemGroup>
<Folder Include="wwwroot\lib\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MP.Data\MP.Data.csproj" />
</ItemGroup>
<ItemGroup>
<Content Update="wwwroot\favicon.ico">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<None Update="logs\.placeholder">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="post-build.ps1">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="powershell.exe -ExecutionPolicy Unrestricted -NoProfile -NonInteractive -File $(ProjectDir)\post-build.ps1 -ProjectDir $(ProjectDir) -ProjectPath $(ProjectPath)" />
</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="Debug" writeTo="consoleTarget" />
<!--<logger name="Microsoft.*" maxlevel="Info" final="true" />-->
<logger name="*" minlevel="Info" writeTo="fileTarget" />
</rules>
</nlog>
+170
View File
@@ -0,0 +1,170 @@
@page "/ART"
@using MP.SPEC.Components
@using MP.SPEC.Data
<div class="card">
<div class="card-header table-primary">
<div class="d-flex justify-content-between">
<div class="px-0">
<div class="d-flex justify-content-between">
<div class="px-2">
<h3>Articoli </h3>
</div>
<div class="px-2">
<button class="btn btn-success" @onclick="() => addNew()">Nuovo <i class="bi bi-plus-square"></i></button>
</div>
</div>
</div>
<div class="px-0 align-content-center">
<div class="input-group input-group">
<label class="input-group-text" for="maxRecord" title="Selezionare l'azienda da visualizzare"><i class="fa-solid fa-industry"></i></label>
<select @bind="@selAzienda" class="form-select" title="Selezionare l'azienda da visualizzare">
@if (ListAziende != null)
{
foreach (var item in ListAziende)
{
<option value="@item.CodGruppo">@item.DescrGruppo</option>
}
}
</select>
</div>
</div>
</div>
@if (currRecord != null)
{
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header bg-primary text-light">Modifica</div>
<div class="card-body">
<div class="row">
<div class="col-4">
<div class="input-group">
<span class="input-group-text">Codice</span>
<input type="text" class="form-control" placeholder="Articolo" @bind-value="@currRecord.CodArticolo">
</div>
</div>
<div class="col-4">
<div class="input-group">
<span class="input-group-text">Disegno</span>
<input type="text" class="form-control" placeholder="Disegno" @bind-value="@currRecord.Disegno">
</div>
</div>
<div class="col-1">
<div class="input-group" title="Tipo">
<select @bind="@currRecord.Tipo" class="form-select text-end">
@if (ListTipoArt != null)
{
foreach (var item in ListTipoArt)
{
<option value="@item.value">@item.label</option>
}
}
</select>
</div>
</div>
<div class="col-3">
<div class="input-group" title="Azienda">
<select @bind="@currRecord.Azienda" class="form-select text-end">
@if (ListAziende != null)
{
foreach (var item in ListAziende.Where(x => x.CodGruppo != "*").ToList())
{
<option value="@item.CodGruppo">@item.DescrGruppo</option>
}
}
</select>
</div>
</div>
</div>
<div class="row mt-2">
<div class="col-8">
<input type="text" class="form-control" placeholder="Descrizione Articolo" @bind-value="@currRecord.DescArticolo">
</div>
<div class="col-2">
<div class="d-grid gap-2">
<button class="btn btn-warning" @onclick="() => cancel()">Annulla <i class="bi bi-x-circle"></i></button>
</div>
</div>
<div class="col-2">
<div class="d-grid gap-2">
<button class="btn btn-success" @onclick="() => update(currRecord)">Salva <i class="bi bi-save"></i></button>
</div>
</div>
</div>
</div>
@*<div class="card-footer">Footer</div>*@
</div>
</div>
</div>
}
</div>
<div class="card-body">
@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">
<thead>
<tr>
<th>
<button @onclick="() => resetSel()" class="btn btn-primary btn-sm"><i class="bi bi-arrow-counterclockwise"></i></button>
</th>
<th><i class="fa-solid fa-file"></i> Articolo</th>
<th><i class="fa-solid fa-compass-drafting"></i> Disegno</th>
<th><i class="fa-solid fa-file-word"></i> Descrizione</th>
<th><i class="fa-solid fa-rectangle-list"></i> Tipo</th>
<th><i class="fa-solid fa-industry"></i> Azienda</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var record in ListRecords)
{
<tr class="@checkSelect(@record.CodArticolo)">
<td>
<button @onclick="() => selRecord(record)" class="btn btn-primary btn-sm"><i class="bi bi-pencil-square"></i></button>
</td>
<td>
<div>@record.CodArticolo</div>
</td>
<td>
<div class="small">@record.Disegno</div>
</td>
<td>
<div class="small">@record.DescArticolo</div>
</td>
<td>
<div>@record.Tipo</div>
</td>
<td>@record.Azienda</td>
<td>
@if (ArticoloDelEnabled(record.CodArticolo))
{
<button @onclick="() => deleteRecord(record)" class="btn btn-danger btn-sm"><i class="bi bi-trash-fill"></i></button>
}
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
}
</div>
<div class="card-footer py-1">
<DataPager PageSize="numRecord" currPage="currPage" numRecordChanged="ForceReload" numPageChanged="ForceReloadPage" totalCount="totalCount" showLoading="isLoading" />
</div>
</div>
+279
View File
@@ -0,0 +1,279 @@
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using MP.Data.DatabaseModels;
using MP.SPEC.Data;
namespace MP.SPEC.Pages
{
public partial class Articoli : ComponentBase, IDisposable
{
#region Public Methods
public string checkSelect(string CodArticolo)
{
string answ = "";
if (currRecord != null)
{
try
{
answ = (currRecord.CodArticolo == CodArticolo) ? "table-info" : "";
}
catch
{ }
}
return answ;
}
public void Dispose()
{
MessageService.EA_SearchUpdated -= OnSeachUpdated;
}
public async void OnSeachUpdated()
{
await InvokeAsync(() =>
{
currPage = 1;
Task task = UpdateData();
StateHasChanged();
});
}
#endregion Public Methods
#region Protected Properties
[Inject]
protected IJSRuntime JSRuntime { get; set; } = null!;
[Inject]
protected MpDataService MDService { get; set; } = null!;
[Inject]
protected MessageService MessageService { get; set; } = null!;
[Inject]
protected NavigationManager NavManager { get; set; }
protected int totalCount
{
get
{
int answ = 0;
if (SearchRecords != null)
{
answ = SearchRecords.Count;
}
return answ;
}
}
#endregion Protected Properties
#region Protected Methods
/// <summary>
/// Crea nuovo record e va in editing...
/// </summary>
/// <returns></returns>
protected async Task addNew()
{
currRecord = new AnagArticoli()
{
CodArticolo = $"_NEW_{DateTime.Now:yyyyMMdd.HHmmss}",
DescArticolo = "Nuovo articolo",
Azienda = selAzienda != "*" ? selAzienda : "MAPO",
Disegno = "",
Tipo = "ART"
};
await Task.Delay(1);
}
protected async Task cancel()
{
currRecord = null;
await reloadData();
await Task.Delay(1);
}
/// <summary>
/// Eliminazione record selezioanto (previa conferma)
/// </summary>
/// <param name="selRec"></param>
/// <returns></returns>
protected async Task deleteRecord(AnagArticoli selRec)
{
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Eliminazione Articolo: sei sicuro di voler procedere?"))
return;
await Task.Delay(1);
var done = await MDService.ArticoliDeleteRecord(selRec);
currRecord = null;
await reloadData();
await Task.Delay(1);
}
protected void ForceReload(int newNum)
{
numRecord = newNum;
}
protected void ForceReloadPage(int newNum)
{
currPage = newNum;
}
protected override async Task OnInitializedAsync()
{
numRecord = 10;
// mostro ricerca
MessageService.ShowSearch = true;
MessageService.EA_SearchUpdated += OnSeachUpdated;
configData = await MDService.ConfigGetAll();
var currRec = configData.FirstOrDefault(x => x.Chiave == "AZIENDA");
if (currRec != null)
{
selAzienda = currRec.Valore;
}
ListAziende = await MDService.ElencoAziende();
ListTipoArt = await MDService.AnagTipoArtLV();
await reloadData();
}
protected void ResetData()
{
currRecord = null;
}
protected async Task resetSel()
{
currRecord = null;
await Task.Delay(1);
}
protected async Task selRecord(AnagArticoli selRec)
{
currRecord = selRec;
await Task.Delay(1);
}
protected async Task update(AnagArticoli selRec)
{
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Confermi di voler salvare le modifiche?"))
return;
await Task.Delay(1);
var done = await MDService.ArticoliUpdateRecord(selRec);
currRecord = null;
await reloadData();
await Task.Delay(1);
}
protected async Task UpdateData()
{
currRecord = null;
await reloadData();
}
#endregion Protected Methods
#region Private Fields
private string _selAzienda = "*";
private AnagArticoli? currRecord = null;
private List<AnagGruppi>? ListAziende;
private List<AnagArticoli>? ListRecords;
private List<ListValues>? ListTipoArt;
private List<AnagArticoli>? SearchRecords;
#endregion Private Fields
#region Private Properties
private int _currPage { get; set; } = 1;
private int _numRecord { get; set; } = 10;
private List<ConfigModel>? configData { get; set; } = null;
private int currPage
{
get => _currPage;
set
{
if (_currPage != value)
{
_currPage = value;
var pUpd = Task.Run(async () => await reloadData());
pUpd.Wait();
}
}
}
private bool isLoading { get; set; } = false;
private int numRecord
{
get => _numRecord;
set
{
if (_numRecord != value)
{
_numRecord = value;
var pUpd = Task.Run(async () => await reloadData());
pUpd.Wait();
}
}
}
private string selAzienda
{
get => _selAzienda;
set
{
if (value != _selAzienda)
{
_selAzienda = value;
var pUpd = Task.Run(async () =>
{
// svuoto cache redis...
ConfigModel updRec = new ConfigModel()
{
Chiave = "AZIENDA",
Valore = value
};
await MDService.ConfigUpdate(updRec);
await MDService.ConfigResetCache();
// ricarico
await Task.Delay(1);
await reloadData();
});
pUpd.Wait();
}
}
}
private bool ShowCharts { get; set; } = false;
#endregion Private Properties
#region Private Methods
/// <summary>
/// Seleziona record x editing
/// </summary>
/// <param name="selRec"></param>
/// <returns></returns>
private bool ArticoloDelEnabled(string codArt)
{
bool answ = MDService.ArticoloDelEnabled(codArt);
return answ;
}
private async Task reloadData()
{
isLoading = true;
SearchRecords = await MDService.ArticoliGetSearch(100000, selAzienda, MessageService.SearchVal);
ListRecords = SearchRecords.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList();
isLoading = false;
}
#endregion Private Methods
}
}
+37
View File
@@ -0,0 +1,37 @@
@page "/DOSS"
<div class="card">
<div class="card-header table-primary">
<div class="d-flex">
<div class="px-0 py-1">
<h3><b>DOSSIERS</b></h3>
</div>
<div class="px-2 flex-fill">
@if (isFiltering)
{
<LoadingDataSmall></LoadingDataSmall>
<i>filtro x macchina / periodo</i>
}
else
{
<DossiersFilter FilterChanged="updateFilter"></DossiersFilter>
}
</div>
</div>
</div>
<div class="card-body">
@if (isLoading)
{
<LoadingData></LoadingData>
}
else
{
<ListDossiers SelFilter="@currFilter" TotRecordChanged="updateTotal"></ListDossiers>
}
</div>
<div class="card-footer py-1">
<DataPager @ref="pagerODL" PageSize="numRecord" currPage="currPage" numRecordChanged="ForceReload" totalCount="totalCount" showLoading="isLoading" />
</div>
</div>
+91
View File
@@ -0,0 +1,91 @@
using Microsoft.AspNetCore.Components;
using MP.SPEC.Components;
using MP.SPEC.Data;
namespace MP.SPEC.Pages
{
public partial class DOSS
{
#region Protected Fields
protected DataPager pagerODL = null!;
#endregion Protected Fields
#region Protected Properties
[Inject]
protected MessageService MsgService { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected void ForceReload(int newNum)
{
numRecord = newNum;
}
protected override async Task OnInitializedAsync()
{
isLoading = true;
isFiltering = true;
// disabilito ricerca...
MsgService.SearchVal = "";
MsgService.ShowSearch = false;
// fix pagina
await Task.Delay(1);
var modFilter = currFilter;
modFilter.CurrPage = 1;
currFilter = modFilter;
await Task.Delay(1);
isFiltering = false;
}
protected void updateTotal(int newTotCount)
{
totalCount = newTotCount;
}
#endregion Protected Methods
#region Private Properties
private SelectDossierParams currFilter { get; set; } = new SelectDossierParams();
private int currPage
{
get => MsgService.currPage;
set => MsgService.currPage = value;
}
private bool isFiltering { get; set; } = false;
private bool isLoading { get; set; } = true;
private int numRecord
{
get => MsgService.numRecord;
set => MsgService.numRecord = value;
}
private int totalCount { get; set; } = 0;
#endregion Private Properties
#region Private Methods
private async Task updateFilter(SelectDossierParams newParams)
{
isFiltering = false;
isLoading = true;
await Task.Delay(1);
currPage = 1;
await Task.Delay(1);
await InvokeAsync(() => StateHasChanged());
currFilter = newParams;
isLoading = false;
}
#endregion Private Methods
}
}
+42
View File
@@ -0,0 +1,42 @@
@page
@model MP.SPEC.Pages.ErrorModel
<!DOCTYPE html>
<html lang="en">
<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/site.css" rel="stylesheet" asp-append-version="true" />
</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>
+27
View File
@@ -0,0 +1,27 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System.Diagnostics;
namespace MP.SPEC.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;
}
}
}
+59
View File
@@ -0,0 +1,59 @@
@page "/"
<PageTitle>Index</PageTitle>
<div class="card">
<div class="card-header bg-dark text-light">
<div class="d-flex justify-content-between">
<div class="p-2">
<img src="images/LogoMapo.png" class="image-fluid" height="64" />
</div>
<div class="p-2 align-content-center fs-1">
<b>MAPO SPEC</b>
</div>
<div class="p-2 bg-light">
<img src="images/LogoEgw.png" class="image-fluid" height="64" />
</div>
</div>
</div>
<div class="card-body text-center">
<div class="shortcuts my-5 py-5">
<div class="row">
<div class="col-12">
@if (ElencoLink == null)
{
<LoadingData></LoadingData>
}
else if (ElencoLink.Count == 0)
{
<div class="alert alert-danger" role="alert">
Nessun record trovato!
</div>
}
else
{
foreach (var item in ElencoLink)
{
<a href="@item.NavigateUrl" class="shortcut">
<i class="@item.icona shortcut-icon"></i>
<span class="shortcut-label">@item.Testo</span>
</a>
}
}
</div>
</div>
</div>
</div>
<dic class="card-footer bg-primary">
<div class="d-flex text-white justify-content-between">
<div class="px-2">
<h1>@currAzienda</h1>
</div>
<div class="px-2">
<h3 class="my-2">MAPO MES Custom Pages</h3>
</div>
</div>
</dic>
</div>
+59
View File
@@ -0,0 +1,59 @@
using Microsoft.AspNetCore.Components;
using MP.Data.DatabaseModels;
using MP.SPEC.Data;
namespace MP.SPEC.Pages
{
public partial class Index
{
#region Public Properties
public List<LinkMenu>? ElencoLink { get; set; }
#endregion Public Properties
#region Protected Properties
[Inject]
protected MpDataService MDService { get; set; } = null!;
[Inject]
protected MessageService MessageService { get; set; }
#endregion Protected Properties
#region Protected Methods
protected override async Task OnInitializedAsync()
{
// nascondo ricerca
MessageService.ShowSearch = false;
// recupero elenco JQM
ElencoLink = await MDService.ElencoLink();
configData = await MDService.ConfigGetAll();
if (configData != null)
{
var currRec = configData.FirstOrDefault(x => x.Chiave == "AZIENDA");
if (currRec != null)
{
currAzienda = currRec.Valore;
}
}
await Task.Delay(1);
}
#endregion Protected Methods
#region Private Fields
private string currAzienda = "";
#endregion Private Fields
#region Private Properties
private List<ConfigModel>? configData { get; set; } = null;
#endregion Private Properties
}
}
+34
View File
@@ -0,0 +1,34 @@
@page "/ODL"
<div class="card">
<div class="card-header table-primary">
<div class="d-flex justify-content-between">
<div class="px-1">
<h3><b>ODL</b></h3>
</div>
<div class="px-2">
<div class="input-group input-group">
<label class="input-group-text" for="maxRecord" title="Selezionare la fase da visualizzare"><i class="fa-solid fa-screwdriver-wrench"></i></label>
<select @bind="@selStato" class="form-select"title="Selezionare la fase da visualizzare">
<option value="*">--- Tutti ---</option>
@if (ListStati != null)
{
foreach (var item in ListStati)
{
<option value="@item.value">@item.label</option>
}
}
</select>
</div>
</div>
</div>
</div>
<div class="card-body">
<ListODL StatoSel="@selStato" PagerResetReq="pgResetReq"></ListODL>
</div>
<div class="card-footer py-1">
<DataPager @ref="pagerODL" PageSize="numRecord" currPage="currPage" numRecordChanged="ForceReload" numPageChanged="ForceReloadPage" totalCount="totalCount" showLoading="isLoading" />
</div>
</div>
+111
View File
@@ -0,0 +1,111 @@
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using MP.SPEC.Components;
using MP.SPEC.Data;
namespace MP.SPEC.Pages
{
public partial class ODL
{
#region Protected Fields
protected DataPager pagerODL;
#endregion Protected Fields
#region Protected Properties
[Inject]
protected IJSRuntime JSRuntime { get; set; } = null!;
[Inject]
protected MpDataService MDService { get; set; } = null!;
[Inject]
protected MessageService MsgService { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected void ForceReload(int newNum)
{
numRecord = newNum;
}
protected void ForceReloadPage(int newNum)
{
currPage = newNum;
}
protected override async Task OnInitializedAsync()
{
// abilito ricerca...
MsgService.ShowSearch = true;
// resetto search
MsgService.SearchVal = "";
ListAziende = await MDService.ElencoAziende();
ListStati = await MDService.AnagStatiComm();
// carico dati
await reloadData();
}
protected async Task pgResetReq(bool doReset)
{
if (doReset)
{
await pagerODL.resetCurrPage();
}
}
#endregion Protected Methods
#region Private Fields
private MP.Data.DatabaseModels.ODLModel? currRecordOdl = null;
private MP.Data.DatabaseModels.PODLModel? currRecordPOdl = null;
private List<MP.Data.DatabaseModels.AnagGruppi>? ListAziende;
private List<MP.Data.DatabaseModels.ListValues>? ListStati;
#endregion Private Fields
#region Private Properties
private string currAzienda { get; set; } = "*";
private int currPage
{
get => MsgService.currPage;
set => MsgService.currPage = value;
}
private bool isLoading { get; set; } = false;
private int numRecord
{
get => MsgService.numRecord;
set => MsgService.numRecord = value;
}
private string selStato { get; set; } = "*";
private int totalCount
{
get => MsgService.totalCount;
set => MsgService.totalCount = value;
}
#endregion Private Properties
#region Private Methods
private async Task reloadData()
{
isLoading = true;
await Task.Delay(1);
isLoading = false;
}
#endregion Private Methods
}
}
+36
View File
@@ -0,0 +1,36 @@
@page "/PARAMS"
<div class="card">
<div class="card-header table-primary">
<div class="d-flex">
<div class="px-0 py-1">
<h3><b>PARAMETERS</b></h3>
</div>
<div class="px-2 flex-fill">
@if (isFiltering)
{
<LoadingDataSmall></LoadingDataSmall>
}
else
{
<ParamsFilter FilterChanged="updateFilter"></ParamsFilter>
}
</div>
</div>
</div>
<div class="card-body">
@if (isLoading)
{
<LoadingData></LoadingData>
}
else
{
<ListPARAMS SelFilter="@currFilter" TotRecordChanged="@updateTotal"></ListPARAMS>
}
</div>
<div class="card-footer py-1">
<DataPager @ref="pagerODL" PageSize="numRecord" currPage="currPage" numRecordChanged="ForceReload" numPageChanged="ForceReloadPage" totalCount="totalCount" showLoading="isLoading" />
</div>
</div>
+122
View File
@@ -0,0 +1,122 @@
using Microsoft.AspNetCore.Components;
using MP.SPEC.Components;
using MP.SPEC.Data;
namespace MP.SPEC.Pages
{
public partial class PARAMS
{
#region Protected Fields
protected DataPager pagerODL = null!;
#endregion Protected Fields
#region Protected Properties
[Inject]
protected MessageService MsgService { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected void ForceReload(int newNum)
{
numRecord = newNum;
}
protected void ForceReloadPage(int newNum)
{
currPage = newNum;
currFilter.lastUpdate= $"Last Snapshot: {DateTime.Now:yyyy/MM/dd HH:mm:ss}";
currFilter.LiveUpdate = (currPage == 1);
StateHasChanged();
}
protected override async Task OnInitializedAsync()
{
isLoading = true;
isFiltering = true;
// disabilito ricerca...
MsgService.SearchVal = "";
MsgService.ShowSearch = false;
// fix pagina
await Task.Delay(1);
var modFilter = currFilter;
modFilter.CurrPage = 1;
modFilter.LiveUpdate = (currPage == 1);
currFilter = modFilter;
await Task.Delay(1);
isFiltering = false;
}
protected async Task pgResetReq(bool doReset)
{
if (doReset)
{
await pagerODL.resetCurrPage();
}
}
protected void updateTotal(int newTotCount)
{
totalCount = newTotCount;
}
#endregion Protected Methods
#region Private Fields
#endregion Private Fields
#region Private Properties
private SelectFluxParams currFilter { get; set; } = new SelectFluxParams();
private int currPage
{
get => MsgService.currPage;
set => MsgService.currPage = value;
}
private bool isLoading { get; set; } = true;
private bool isFiltering { get; set; } = false;
private int numRecord
{
get => MsgService.numRecord;
set => MsgService.numRecord = value;
}
private int totalCount { get; set; } = 0;
#endregion Private Properties
#region Private Methods
private async Task updateFilter(SelectFluxParams newParams)
{
isFiltering = false;
isLoading = true;
await Task.Delay(1);
currPage = 1;
if (newParams.CurrPage == 0)
{
newParams.CurrPage = 1;
newParams.LiveUpdate = false;
}
else
{
newParams.LiveUpdate = (currPage == 1);
}
await Task.Delay(1);
await InvokeAsync(() => StateHasChanged());
currFilter = newParams;
isLoading = false;
}
#endregion Private Methods
}
}
+207
View File
@@ -0,0 +1,207 @@
@page "/PODL"
<div class="card">
<div class="card-header table-primary">
<div class="d-flex justify-content-between">
<div class="col-6">
<div class="d-flex">
<div class="px-2">
<h3><b>P</b>romesse <b>ODL</b></h3>
</div>
<div class="px-2">
@if (addEnabled)
{
<button class="btn btn-success" @onclick="() => reqNewPODL()">@btnNewText <i class="bi bi-plus-square"></i></button>
}
</div>
</div>
</div>
<div class="col-6">
<div class="input-group input-group-sm">
<label class="input-group-text" for="maxRecord" title="Selezionare l'azienda da visualizzare"><i class="fa-solid fa-industry"></i></label>
<select @bind="@currAzienda" class="form-select" title="Selezionare l'azienda da visualizzare">
@if (ListAziende != null)
{
foreach (var item in ListAziende)
{
<option value="@item.CodGruppo">@item.DescrGruppo</option>
}
}
</select>
<label class="input-group-text" for="maxRecord" title="Selezionare la fase da visualizzare"><i class="fa-solid fa-screwdriver-wrench"></i></label>
<select @bind="@selStato" class="form-select" title="Selezionare la fase da visualizzare">
<option value="*">--- Tutti ---</option>
@if (ListStati != null)
{
foreach (var item in ListStati)
{
<option value="@item.value">@item.label</option>
}
}
</select>
</div>
</div>
</div>
@if (currRecord != null)
{
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header bg-primary text-light">Modifica PODL</div>
<div class="card-body">
<div class="row">
<div class="col-6">
<div class="row">
<div class="col-3 pe-0">
<div class="input-group input-group-sm">
<span class="input-group-text" id="inputGroup-sizing-sm">Search</span>
<input type="text" class="form-control" aria-label="Art search" aria-describedby="inputGroup-sizing-sm" @bind-value="@artSearch">
</div>
</div>
<div class="col-9 ps-0">
<div class="input-group input-group-sm">
<span class="input-group-text" id="inputGroup-sizing-sm">Articolo</span>
<select @bind="@currRecord.CodArticolo" class="form-select">
@if (ListArticoli != null)
{
foreach (var item in ListArticoli.Where(x => x.Azienda == currAzienda).ToList())
{
<option value="@item.CodArticolo">@item.CodArticolo | @item.DescArticolo | @item.Disegno</option>
}
}
</select>
</div>
</div>
</div>
</div>
<div class="col-3">
</div>
<div class="col-3">
<div class="input-group input-group-sm">
<span class="input-group-text" id="inputGroup-sizing-sm">Fase</span>
<select @bind="@currRecord.KeyRichiesta" class="form-select">
@if (ListStati != null)
{
foreach (var item in ListStati)
{
<option value="@item.value">@item.label</option>
}
}
</select>
</div>
</div>
</div>
<div class="row mt-2">
<div class="col-3">
<div class="input-group input-group-sm">
<div class="input-group input-group-sm">
<span class="input-group-text" id="inputGroup-sizing-sm">Gruppo</span>
<select @bind="@currRecord.CodGruppo" class="form-select">
@if (ListGruppiFase != null)
{
foreach (var item in ListGruppiFase)
{
<option value="@item.CodGruppo">@item.CodGruppo | @item.DescrGruppo</option>
}
}
</select>
</div>
</div>
</div>
<div class="col-3">
<div class="input-group input-group-sm">
<div class="input-group input-group-sm">
<div class="input-group input-group-sm">
<span class="input-group-text" id="inputGroup-sizing-sm">Macchina</span>
<select @bind="@currRecord.IdxMacchina" class="form-select">
@if (ListMacchine != null)
{
foreach (var item in ListMacchine)
{
<option value="@item.IdxMacchina">@item.IdxMacchina | @item.Descrizione</option>
}
}
</select>
</div>
</div>
</div>
</div>
<div class="col-3">
<div class="d-grid gap-2">
<button class="btn btn-warning" @onclick="() => cancel()">Annulla <i class="bi bi-x-circle"></i></button>
</div>
</div>
<div class="col-3">
<div class="d-grid gap-2">
<button class="btn btn-success" @onclick="() => update(currRecord)">Salva <i class="bi bi-save"></i></button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
}
else if (addEnabled)
{
<div class="row">
<div class="col-4">
@*<button class="btn btn-success" @onclick="() => reqNewPODL()">@btnNewText <i class="bi bi-plus-square"></i></button>*@
</div>
@if (reqNew)
{
<div class="col-4">
<div class="input-group input-group-sm">
<span class="input-group-text" id="inputGroup-sizing-sm">Azienda</span>
<select @bind="@currAzienda" class="form-select">
@if (ListAziende != null)
{
foreach (var item in ListAziende.Where(x => x.CodGruppo != "*").ToList())
{
<option value="@item.CodGruppo">@item.DescrGruppo</option>
}
}
</select>
</div>
</div>
<div class="col-4">
<div class="input-group input-group-sm">
<span class="input-group-text" id="inputGroup-sizing-sm">Search</span>
<input type="text" class="form-control" aria-label="Art search" aria-describedby="inputGroup-sizing-sm" @bind-value="@artSearch">
<span class="input-group-text" id="inputGroup-sizing-sm">Articolo</span>
<select @bind="@currArticolo" class="form-select">
@if (ListArticoli != null)
{
foreach (var item in ListArticoli.Where(x => x.Azienda == currAzienda).ToList())
{
<option value="@item.CodArticolo">@item.CodArticolo | @item.DescArticolo | @item.Disegno</option>
}
}
</select>
</div>
</div>
}
</div>
}
</div>
<div class="card-body">
@if (isLoading)
{
<LoadingData></LoadingData>
}
else
{
<ListPODL PagerResetReq="pgResetReq" RecordSel="@selRecord"></ListPODL>
}
</div>
<div class="card-footer py-1">
<DataPager @ref="pagerODL" PageSize="numRecord" currPage="currPage" numRecordChanged="ForceReload" numPageChanged="ForceReloadPage" totalCount="totalCount" showLoading="isLoading" />
</div>
</div>
+280
View File
@@ -0,0 +1,280 @@
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using MP.Data.DatabaseModels;
using MP.SPEC.Components;
using MP.SPEC.Data;
namespace MP.SPEC.Pages
{
public partial class PODL
{
#region Protected Fields
protected DataPager pagerODL;
protected bool reqNew = false;
#endregion Protected Fields
#region Protected Properties
[Inject]
protected IJSRuntime JSRuntime { get; set; }
[Inject]
protected MpDataService MDService { get; set; }
[Inject]
protected MessageService MsgService { get; set; }
[Inject]
protected NavigationManager NavManager { get; set; }
#endregion Protected Properties
#region Protected Methods
/// <summary>
/// Crea nuovo record e va in editing...
/// </summary>
/// <returns></returns>
protected async Task addNew()
{
currRecord = new PODLModel()
{
CodArticolo = $"_NEW_{DateTime.Now:yyyyMMdd.HHmmss}"
};
await Task.Delay(1);
}
protected async Task cancel()
{
currRecord = null;
await reloadData();
await Task.Delay(1);
}
protected void ForceReload(int newNum)
{
numRecord = newNum;
}
protected void ForceReloadPage(int newNum)
{
currPage = newNum;
}
protected override async Task OnInitializedAsync()
{
// abilito ricerca...
MsgService.ShowSearch = true;
// resetto search
MsgService.SearchVal = "";
ListAziende = await MDService.ElencoAziende();
ListGruppiFase = await MDService.ElencoGruppiFase();
ListMacchine = await MDService.MacchineGetAll();
ListStati = await MDService.AnagStatiComm();
// preselezione valori
configData = await MDService.ConfigGetAll();
var currRec = configData.FirstOrDefault(x => x.Chiave == "AZIENDA");
if (currRec != null)
{
currAzienda = currRec.Valore;
}
// carico dati
await reloadData();
}
protected async Task pgResetReq(bool doReset)
{
if (doReset)
{
await pagerODL.resetCurrPage();
}
}
/// <summary>
/// Crea nuovo record e va in editing...
/// </summary>
/// <returns></returns>
protected async Task reqNewPODL()
{
// aggiungo record articolo
currArticolo = "";
if (ListArticoli != null && ListArticoli.Count > 0)
{
var firstArt = ListArticoli.FirstOrDefault();
currArticolo = firstArt != null ? firstArt.CodArticolo : "";
}
string codExt = $"{selStato}";
string codGruppo = "";
if (ListGruppiFase != null && ListGruppiFase.Count > 0)
{
var firstFase = ListGruppiFase.FirstOrDefault(x => x.CodGruppo.StartsWith(_currAzienda));
if (firstFase != null)
{
codGruppo = firstFase.CodGruppo;
}
}
string codMacc = "";
if (ListMacchine != null && ListMacchine.Count > 0)
{
var firstMacc = ListMacchine.FirstOrDefault(x => x.Nome.Contains(currAzienda));
if (firstMacc != null)
{
codMacc = firstMacc.IdxMacchina;
}
}
currRecord = new PODLModel()
{
CodArticolo = currArticolo,
KeyBCode = codExt,
KeyRichiesta = codExt,
CodGruppo = codGruppo,
IdxMacchina = codMacc,
NumPezzi = 1,
DueDate = DateTime.Now.AddDays(30)
};
await Task.Delay(1);
}
protected async Task selRecord(PODLModel selRec)
{
currRecord = selRec;
await Task.Delay(1);
}
protected async Task update(PODLModel selRec)
{
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Confermi di voler salvare le modifiche?"))
return;
await Task.Delay(1);
var done = await MDService.POdlUpdateRecord(selRec);
currRecord = null;
await reloadData();
await Task.Delay(1);
}
#endregion Protected Methods
#region Private Fields
private PODLModel? _currRecord = null;
private List<AnagArticoli>? ListArticoli;
private List<AnagGruppi>? ListAziende;
private List<AnagGruppi>? ListGruppiFase;
private List<Macchine>? ListMacchine;
private List<ListValues>? ListStati;
#endregion Private Fields
#region Private Properties
private string _artSearch { get; set; } = "";
private string _currAzienda { get; set; } = "*";
private bool addEnabled
{
get => selStato != "*";
}
private string artSearch
{
get => _artSearch;
set
{
if (!_artSearch.Equals(value))
{
_artSearch = value;
var pUpd = Task.Run(async () =>
{
await reloadData();
});
pUpd.Wait();
}
}
}
private string btnNewText
{
get => currArticolo == "" ? "Sel Articolo" : "Nuovo PODL";
}
private List<ConfigModel>? configData { get; set; } = null;
private string currArticolo { get; set; } = "";
private string currAzienda
{
get => _currAzienda;
set
{
if (!_currAzienda.Equals(value))
{
_currAzienda = value;
var pUpd = Task.Run(async () =>
{
await reloadData();
});
pUpd.Wait();
}
}
}
private int currPage
{
get => MsgService.currPage;
set => MsgService.currPage = value;
}
private PODLModel? currRecord
{
get => _currRecord;
set
{
_currRecord = value;
artSearch = value == null ? "" : value.CodArticolo;
}
}
private bool isLoading { get; set; } = false;
private int numRecord
{
get => MsgService.numRecord;
set => MsgService.numRecord = value;
}
private string selStato
{
get => MsgService.StateSel;
set => MsgService.StateSel = value;
}
private int totalCount
{
get => MsgService.totalCount;
set => MsgService.totalCount = value;
}
#endregion Private Properties
#region Private Methods
private async Task reloadData()
{
isLoading = true;
await Task.Delay(1);
if (currAzienda != "*")
{
ListArticoli = await MDService.ArticoliGetSearch(100, currAzienda, artSearch);
}
else
{
ListArticoli = new List<AnagArticoli>();
}
isLoading = false;
}
#endregion Private Methods
}
}
+10
View File
@@ -0,0 +1,10 @@
@page "/Utils"
@using MP.SPEC.Components
@using MP.SPEC.Data
<h3>Utils</h3>
<div class="px-2">
<button class="btn btn-primary" @onclick="() => flushCache()"> Flush Cache </button>
</div>
+18
View File
@@ -0,0 +1,18 @@
using Microsoft.AspNetCore.Components;
using MP.SPEC.Data;
using System.Reflection;
namespace MP.SPEC.Pages
{
public partial class Utils
{
[Inject]
protected MpDataService MDService { get; set; }
public async Task flushCache()
{
await Task.Delay(1);
await MDService.FlushRedisCache();
}
}
}
+8
View File
@@ -0,0 +1,8 @@
@page "/"
@namespace MP.SPEC.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
Layout = "_Layout";
}
<component type="typeof(App)" render-mode="Server" />
+57
View File
@@ -0,0 +1,57 @@
@using Microsoft.AspNetCore.Components.Web
@namespace MP.SPEC.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="google" content="notranslate">
<base href="~/" />
<link rel="stylesheet" href="lib/bootstrap/css/bootstrap.min.css" />
<link rel="stylesheet" href="lib/bootstrap-icons/font/bootstrap-icons.min.css" />
<link rel="stylesheet" href="css/site.min.css" />
<link rel="stylesheet" href="lib/font-awesome/css/all.min.css" />
<link href="MP.SPEC.styles.css" rel="stylesheet" />
<component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" />
</head>
<body>
@RenderBody()
<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>
<script src="_framework/blazor.server.js" autostart="false"></script>
@*Gestione autoriconnessione: https://github.com/dotnet/aspnetcore/issues/38305 (vedere anche https://docs.microsoft.com/it-it/aspnet/core/blazor/fundamentals/signalr?view=aspnetcore-6.0#modify-the-reconnection-handler-blazor-server)*@
<script>
Blazor.start({
reconnectionOptions: {
maxRetries: 300,
retryIntervalMilliseconds: 2000
}
}).then(() => {
Object.defineProperty(Blazor.defaultReconnectionHandler, '_reconnectionDisplay', {
get() {
return this.__reconnectionDisplay;
},
set(value) {
this.__reconnectionDisplay = {
show: () => value.show(),
update: (d) => value.update(d),
rejected: (d) => document.location.reload()
}
}
});
});
</script>
</body>
</html>
+63
View File
@@ -0,0 +1,63 @@
using Microsoft.AspNetCore.Authentication.Negotiate;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using MP.SPEC.Components;
using MP.SPEC.Data;
using StackExchange.Redis;
var builder = WebApplication.CreateBuilder(args);
/*--------------------
* Note migrazione startup.cs -_> program.cs:
*
* - https://stackoverflow.com/questions/69722872/asp-net-core-6-how-to-access-configuration-during-startup
* - https://docs.microsoft.com/en-us/aspnet/core/migration/50-to-60?view=aspnetcore-5.0&tabs=visual-studio#where-do-i-put-state-that-was-stored-as-fields-in-my-program-or-startup-class
*
* */
ConfigurationManager configuration = builder.Configuration;
// REDIS setup
string connStringRedis = configuration.GetConnectionString("Redis");
string redisSrvAddr = connStringRedis.Substring(0, connStringRedis.IndexOf(":"));
// avvio oggetto shared x redis...
var redisMultiplexer = ConnectionMultiplexer.Connect(connStringRedis);
// Add services to the container.
builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
.AddNegotiate();
builder.Services.AddAuthorization(options =>
{
// By default, all incoming requests will be authorized according to the default policy.
options.FallbackPolicy = options.DefaultPolicy;
});
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddSingleton<IConnectionMultiplexer>(redisMultiplexer);
builder.Services.AddSingleton<MpDataService>();
builder.Services.AddScoped<MessageService>();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
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();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");
app.Run();
@@ -0,0 +1,19 @@
<?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\net6.0\</PublishUrl>
....<WebPublishMethod>FileSystem</WebPublishMethod>
....<SiteUrlToLaunchAfterPublish />
....<TargetFramework>net6.0</TargetFramework>
....<SelfContained>false</SelfContained>
..</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.egalware.com:8172/MsDeploy.axd</MSDeployServiceURL>
<DeployIisAppPath>Default Web Site/MP/SPEC</DeployIisAppPath>
<RemoteSitePhysicalPath />
<SkipExtraFilesOnServer>False</SkipExtraFilesOnServer>
<MSDeployPublishMethod>WMSVC</MSDeployPublishMethod>
<EnableMSDeployBackup>True</EnableMSDeployBackup>
<UserName>jenkins</UserName>
<_SavePWD>True</_SavePWD>
<TargetFramework>net6.0</TargetFramework>
<EnableMsDeployAppOffline>True</EnableMsDeployAppOffline>
</PropertyGroup>
</Project>

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