794 Commits

Author SHA1 Message Date
Samuele Locatelli 3e0dbd22a4 Fix naming 2025-03-22 11:33:03 +01:00
Samuele Locatelli d7757cf0db Test deploy versione smart 8 su office 2025-03-22 11:31:38 +01:00
Samuele Locatelli 03db156f99 Spostamento componenti top/footer + altri test rendering 2025-03-22 11:05:20 +01:00
Samuele Locatelli 15be702f29 Pulizia + publish 2025-03-21 19:31:25 +01:00
Samuele Locatelli ababa059e9 Aggiunto publish su IIS01 (e altri da testare) 2025-03-21 19:31:18 +01:00
Samuele Locatelli f14f92d73f Creazione progetto Blazor 8 wes (server + WASM) x SMART, da completare... 2025-03-21 18:52:42 +01:00
Samuele Locatelli a3e3c14ee7 Fx conf core con errori che non girava in prod 2025-02-05 08:50:41 +01:00
Samuele Locatelli 47247090d8 Update API + WRKLOG 2025-02-04 18:52:41 +01:00
Samuele Locatelli 2c38306ab5 Update nuget SMART e WRKLOG 2025-02-04 18:50:06 +01:00
Samuele Locatelli 76a91c283d ancora nuget tryfix 2025-02-04 18:42:20 +01:00
Samuele Locatelli 44797c7b51 yaml test fix nuget 2025-02-04 18:41:16 +01:00
Samuele Locatelli 815952e575 refresh nuget 2025-02-04 18:38:41 +01:00
Samuele Locatelli 803f75ac9b Merge remote-tracking branch 'origin/net8.0' into net8.0 2025-02-04 18:36:30 +01:00
Samuele Locatelli 6a78203b97 Correzione calcolo eventi malattia ( fino alle 23:59) 2025-02-04 18:35:14 +01:00
Samuele Locatelli 7b20cb3b3d Update Nuget x iniziare correzioni diario scheduler radzen 2025-02-04 18:17:50 +01:00
Samuele E. Locatelli 1f934d579c Fix compilazione proj CORE.SMART 2024-12-30 14:40:05 +01:00
Samuele E. Locatelli 1db1024020 Fix calcolo weekdata su fine anno 2024-12-30 14:03:35 +01:00
Samuele Locatelli 4097c701d0 Refresh compilazione 2024-12-28 09:57:42 +01:00
Samuele Locatelli f3d7d49e87 WRKLOG:
- Fix gestione spostamento inizio/fine anno su sel week
2024-12-27 18:52:51 +01:00
Samuele Locatelli cdd1a1a29f Typo 2024-10-23 19:22:19 +02:00
Samuele Locatelli f5eda3686d ADM
- continuo fix traduzione
- inizio pagina tag mensili
2024-10-12 17:04:36 +02:00
Samuele Locatelli 38401093df Inizio gestione UserLang corretta 2024-10-12 16:08:01 +02:00
Samuele Locatelli ff75bc3d68 Update: ok gestione orari (base) 2024-10-04 09:25:50 +02:00
Samuele Locatelli ac5c8b3880 ADM:
- Update gestione spostamento fasi con stored clona/sposta
- gestione abilitazione rapida azioni da stato sel
- ottimizzazione meccanismo preselezione cli/proj
2024-10-03 10:04:19 +02:00
Samuele Locatelli b072312a71 ADM
- ok gestione gruppi
- update spostamento fasi
2024-10-02 09:34:46 +02:00
Samuele Locatelli f6b6174ab3 Fix approvazione timbrature fine giornata (23.59.59) che NON vanno arrotondate 2024-09-30 19:57:18 +02:00
Samuele Locatelli d74b92db7d Fix export commesse da elenco timbr 2024-09-17 09:25:47 +02:00
Samuele Locatelli 841c8ddc26 Fix comportmaneto sel timing richieste anche SMART 2024-09-16 12:13:25 +02:00
Samuele Locatelli 9a248d5219 Fix gestione sel periodo ammesso x richiesta ferie/permessi 2024-09-16 12:10:25 +02:00
Samuele Locatelli 5d319b750b Completata revisione gesstione cert malattia da ADM nuovo 2024-09-16 11:32:21 +02:00
Samuele Locatelli 8b2679b878 Fix blazored in WORKLOG 2024-09-16 11:22:03 +02:00
Samuele Locatelli 404b49bb4d Update ADM
- tolto controllo tempi su cambio tipo richiesta (non ha senso...)
- update note permesso
- update metodi Approva/Rifiuta (naming & co)
2024-09-16 11:21:52 +02:00
Samuele Locatelli 1ab60db8fe Update DataLayer
- update metodi x gest richieste
- update API
- update WRKLog
- update ADM
2024-09-16 10:23:24 +02:00
Samuele Locatelli 541ef293cc COmpletato ricalcolo + trace tempi 2024-09-14 09:44:28 +02:00
Samuele Locatelli 1cf9bc3335 Prima bozza ricalcolo (da valutare di nuovo...) 2024-09-13 19:29:29 +02:00
Samuele Locatelli f853a96179 Completato display commesse in elenco timbrature 2024-09-13 18:37:54 +02:00
Samuele Locatelli ea223b57b9 Fix editing giustificativi! completo! 2024-09-13 18:09:48 +02:00
Samuele Locatelli 7147fd0cb7 Ok fino alla gestione giustificativi add/delete... 2024-09-13 17:18:53 +02:00
Samuele Locatelli fa845a823f Update ancora gest timbrature 2024-09-13 15:39:31 +02:00
Samuele Locatelli 6bcea21059 Aggiunto dettaglio timbrature 2024-09-13 15:39:24 +02:00
Samuele Locatelli b910b8439c Completata gestione approvazione timb 2024-09-13 09:21:27 +02:00
Samuele Locatelli 2b0d24421c Abbozzato display approv timbrature 2024-09-12 19:18:21 +02:00
Samuele Locatelli 328ce7dd48 Ancora fix fasi 2024-09-12 18:50:51 +02:00
Samuele Locatelli 1f6af30daf Ok gest TagFasi... 2024-09-12 18:50:44 +02:00
Samuele Locatelli 5b1e04ae48 Fix update nuget progetti WRKLOG e SMART 2024-09-12 16:06:51 +02:00
Samuele Locatelli 30b9c7e662 Fix display ferie (si chiudono a emzzanotte dell'ultimo giorno...) 2024-09-12 16:04:17 +02:00
Samuele Locatelli 2867b1a5d9 Completato editing chiusure aziendali! 2024-09-12 15:46:02 +02:00
Samuele Locatelli d30d5d1d0a Completata gest cert malattia 2024-09-12 10:58:04 +02:00
Samuele Locatelli cec0ab3fc8 Refresh componente paginazione 2024-09-12 10:03:15 +02:00
Samuele Locatelli abdfd82b0a Completata gestione con filtraggio x calendario e elenco 2024-09-12 10:02:06 +02:00
Samuele Locatelli 08c746feb6 Update comportamento selezione eventi calendario approva richieste 2024-09-12 08:56:56 +02:00
Samuele Locatelli 53fa89e571 Update gestione confermati/tutti mostrato 2024-09-11 19:29:06 +02:00
Samuele Locatelli db8d92cd96 Bozza gestione richieste
- approvazione/rifiuto
- gest base calendari
2024-09-11 18:51:07 +02:00
Samuele Locatelli 6bff05f8d4 Completate funzioni editing fasi (base) 2024-09-11 17:06:15 +02:00
Samuele Locatelli 4842e8d81f Update gest AnagFasi 2024-09-11 12:10:17 +02:00
Samuele Locatelli 4ddb77bcaf Continuo update Fasi, compila! 2024-09-11 10:12:30 +02:00
Samuele Locatelli 578477040f Abbozzato comportamento con display Fas del proj 2024-09-10 18:57:27 +02:00
Samuele Locatelli 9edcc17479 Fix vers number 2024-09-10 18:36:07 +02:00
Samuele Locatelli abb64f1565 Update componenti x gestione progetti.. 2024-09-10 18:33:49 +02:00
Samuele Locatelli 7a3696bf3c Aggiunta profili pubblicazione su server IIS 2024-09-10 18:33:41 +02:00
Samuele Locatelli 86015d13ae Pagina progetti:
- Update gestione filtri
- aggiunta BTN x select/fasi
- fix comportamento filtri
2024-09-10 12:10:29 +02:00
Samuele Locatelli 2812bb6aea Update gestione progetti (inizio con display...) 2024-09-10 10:48:48 +02:00
Samuele Locatelli 06d9d00975 Altre pag WIP 2024-09-09 18:42:49 +02:00
Samuele Locatelli 897432d994 Aggiunta altre pagine WIP 2024-09-09 18:40:04 +02:00
Samuele Locatelli dca3ad5847 - cleanup pagine inutilizzate + prime pagine WIP
- fix navMenu
- fix vari
2024-09-09 17:38:12 +02:00
Samuele Locatelli 95fa52a3ff Ok pagina iniziale gest clienti 2024-09-09 17:37:31 +02:00
Samuele Locatelli 0e1e95d77a Aggiunto costruzione NAvMenu laterale da permessi 2024-09-09 12:17:51 +02:00
Samuele Locatelli b7bd4d72ec iAggiunta preliminare progetto ADM in cui fare porting parte ADMIN 2024-09-07 12:24:50 +02:00
Samuele Locatelli 230c6a3efc Aggiunta preliminare progetto ADM 2024-09-07 12:24:46 +02:00
Samuele Locatelli b1afa82a91 Continuo spostamento servizi in Data:
- GpwDataSrvice
- MessageService
- ogni dipendenza (aggiunti using, in _import non basta...)
2024-09-07 11:40:28 +02:00
Samuele Locatelli a8ec6f6e0f Riorganizzazione servizi
- spostato servizio gest licenze in DataProj
- update WRKLOG proj
2024-09-07 11:23:48 +02:00
Samuele Locatelli 565c20e396 WRKLOG
- spostamento sel calendario inDataLayer
- Fix display info personali in dettaglio DTO
- Fix selettore mese
- Clòeanup vari
2024-09-07 10:33:10 +02:00
Samuele Locatelli adaa2657be Fix reload x cambio anno... 2024-09-06 19:01:01 +02:00
Samuele Locatelli 978b1837fe Fix selezione periodo sul controllo 2024-09-06 18:18:49 +02:00
Samuele Locatelli bc58630463 Add sel calendario x gestione anno 2024-09-06 18:00:16 +02:00
Samuele Locatelli 94245a0a44 Calendario Radzen
- sostituito cal precedente
- fix comportamento di base
- ok navigazione di base
2024-09-06 17:35:34 +02:00
Samuele Locatelli b25ddf87b1 Fix nuovo calendario RadZen 2024-09-06 12:09:16 +02:00
Samuele Locatelli 3c106a4e5d Update calendario 2024-09-05 16:22:19 +02:00
Samuele Locatelli 807920341b Fix display calendar SMART & WRKLOG 2024-09-05 15:16:39 +02:00
Samuele Locatelli 3173393e8d Update SMART:
- render mode in app.razor
- reload in app.razro
- update nuget
- fix comportamento pagina DayOff
- cleanup generale
2024-09-05 12:57:21 +02:00
Samuele Locatelli 6a86c235cc Fix: rimosso prerender 2024-09-05 09:24:30 +02:00
Samuele Locatelli 80b058d524 Update:
- fix grafica/interattività
- rimozione compo proj inutilizzato
2024-09-05 09:06:42 +02:00
Samuele Locatelli bb4a3ce94d Update WRKLOG:
- fix code behind
- fix chiamate [Parameters] in auto mode
- fix vari onParameterSetAsync
2024-09-04 19:19:55 +02:00
Samuele Locatelli de1ff13988 Cleanup vari
- if false
- nuget non utilizzati
- warnings
- riorganizzazione codice interno chiamate x WRKLOG (in code behind)
2024-09-04 19:19:14 +02:00
Samuele Locatelli e1342d08c2 Porting API a Blazor 8 2024-09-04 18:38:33 +02:00
Samuele Locatelli da9300cd6b WRKLOG:
- update x pubblicazione iis01
- pulizia warnings vari
2024-09-04 18:38:23 +02:00
Samuele Locatelli f2fcbb2f75 Fix ps1 x compilazione versione csproj 2024-09-04 17:59:17 +02:00
Samuele Locatelli 25eb7f1dc3 Completato fix Blazor 8! 2024-09-04 17:55:06 +02:00
Samuele Locatelli 109a16070f Continuo migrazione... 2024-09-04 15:28:52 +02:00
Samuele Locatelli 5722ad4167 WRKLOG 8.0
- porting blazor 8.0
- riorganizzazione area components
- add componenti da 6
- spostamento ver 6 a old (migrata comunque)
2024-09-04 15:28:37 +02:00
Samuele Locatelli ddcca0583a Aggiunta progetto test AD da 6 --> 8 per fare nuovo sito 2024-08-27 17:46:10 +02:00
Samuele Locatelli 77476cea54 Creato copia OLD del sito dotNet6.0 2024-08-27 17:44:36 +02:00
Samuele Locatelli 378a82074d Continuo Upgrade prj Net6 --> Net8 2024-08-27 13:04:24 +02:00
Samuele Locatelli 2ab73d94f3 update yaml x proj smart senza 6... 2024-08-27 12:58:50 +02:00
Samuele Locatelli 9193237995 update sln x progetto SOLO 8 x CORE.Smart 2024-08-27 12:48:26 +02:00
Samuele Locatelli 27687a85cf Update gestione calendario versione net8 2024-08-27 10:55:27 +02:00
Samuele Locatelli 045e8e5363 Completato fix display ferie/permessi! 2024-08-23 17:01:24 +02:00
Samuele Locatelli 7251a81794 Bozza filtro tipo fermate, DA RIVEDERE!!!! 2024-08-23 16:41:37 +02:00
Samuele Locatelli 29bebbdd7b Update componenti x dsplay calendario 2024-08-23 16:16:08 +02:00
Samuele Locatelli d01bfa97b1 Fix vari da errori rimasti 2024-08-23 14:20:52 +02:00
Samuele Locatelli 9089dfea44 Cleanup warning + calcolo versione framework NET 2024-08-23 13:10:21 +02:00
Samuele Locatelli 5b62ae2b55 Update compilazione vers 8.0 2024-08-23 12:55:02 +02:00
Samuele Locatelli 0ba78dbd4e Aggiunto manifest x pubblicazione come install su mobile + refresh vari 2024-08-23 12:27:04 +02:00
Samuele Locatelli 2e91431129 Gestione base URL 2024-08-23 12:26:50 +02:00
Samuele Locatelli d805de405b Aggiunto profili pubblicazione 2024-08-23 12:26:34 +02:00
Samuele Locatelli 6b6d47d71b COmpletato fix EFCore x tabelel con triggers attivi (NON scrive) 2024-08-22 18:58:03 +02:00
Samuele Locatelli 77cb1efc2a Completata review gestione chiave e sua scadenza 2024-08-22 18:26:21 +02:00
Samuele Locatelli 08656c7404 Cambio colore x mostrare nuova versione blazor 8... 2024-08-22 17:33:27 +02:00
Samuele Locatelli 3e902c72fe Primo ok a caricamento pagina SMART 2024-08-22 17:12:44 +02:00
Samuele Locatelli bc70a085c3 Continuato/completato portiing componenti, ma ancora non sono linkati correttametne 2024-08-22 16:37:41 +02:00
Samuele Locatelli 848b6537d2 Update x nuovo proj 8 2024-08-22 16:03:31 +02:00
Samuele Locatelli 55473e9081 update proj Data a net.8 2024-08-22 15:23:41 +02:00
Samuele Locatelli a881ae9079 Ancora test x upgrade a net 8 su progetto test 2024-08-22 15:01:05 +02:00
Samuele Locatelli f4f2b7c857 Merge branch 'net8.0' of https://gitlab.steamware.net/steamware/gpw_next into net8.0 2024-08-19 10:44:34 +02:00
Samuele Locatelli 3d6e818b8d Update connString user 2024-08-19 10:44:30 +02:00
Samuele E. Locatelli ec48ab08b0 Aggiunto servizio server clock (NON ok) 2024-08-15 15:36:14 +02:00
Samuele Locatelli d5a2406704 update x cache parametri su prerendering 2024-08-09 18:43:57 +02:00
Samuele Locatelli 2044515ce4 Bozza soluzione hybrid dotnet 8.0 2024-08-09 18:10:41 +02:00
Samuele Locatelli 3000a43330 Merge tag 'FixReloadHome01' into develop
Update gestione reset rilettura pagina
2024-08-07 16:23:51 +02:00
Samuele Locatelli 61fafe9236 Merge branch 'release/FixReloadHome01' 2024-08-07 16:23:23 +02:00
Samuele Locatelli 3879bcc6f3 Reorg codice 2024-08-07 16:22:39 +02:00
Samuele Locatelli b678109ec0 Update reload home 2024-08-07 16:16:53 +02:00
Samuele Locatelli 67a3f582bf Merge tag 'FixEntrataStep01' into develop
Fix gestione arrotondamento entrata in worklog
2024-08-05 19:29:43 +02:00
Samuele Locatelli 0d08c57112 Merge branch 'release/FixEntrataStep01' 2024-08-05 19:29:08 +02:00
Samuele Locatelli a62d1688b1 Fix calcolo e display giornata cona rrotondamento ingresso 2024-08-05 19:28:17 +02:00
Samuele Locatelli d3ef9ce45f Merge tag 'AddRobotCacheVeto06' into develop
Fix commenti in RegNewDevice
2024-07-23 12:08:21 +02:00
Samuele Locatelli 46f3146d85 Merge branch 'release/AddRobotCacheVeto06' 2024-07-23 12:08:14 +02:00
Samuele Locatelli 22c9e1186c Fix commenti anche in regNewDevice 2024-07-23 12:08:02 +02:00
Samuele Locatelli e60dc2e172 Merge tag 'AddRobotCacheVeto05' into develop
Fix typo commento reset pagine offline
2024-07-23 11:55:07 +02:00
Samuele Locatelli 14bcf025e0 Merge branch 'release/AddRobotCacheVeto05' 2024-07-23 11:54:57 +02:00
Samuele Locatelli 0713f3d52d Typo commento 2024-07-23 11:54:39 +02:00
Samuele Locatelli 10ce6709dc Merge tag 'AddRobotCacheVeto04' into develop
Aggiunto link istruzioni x fix pagine offline
2024-07-23 11:41:59 +02:00
Samuele Locatelli b415cb6b53 Merge branch 'release/AddRobotCacheVeto04' 2024-07-23 11:41:43 +02:00
Samuele Locatelli 1ccfd55a1c Aggiunta nota x fix gestione pagine offline 2024-07-23 11:41:27 +02:00
Samuele Locatelli bcea43806b Merge tag 'AddRobotCacheVeto03' into develop
Fix typo nocache e levato overlay che non funziona
2024-07-23 11:11:43 +02:00
Samuele Locatelli e1de4d2bde Merge branch 'release/AddRobotCacheVeto03' 2024-07-23 11:11:31 +02:00
Samuele Locatelli 5f7ce2ee5c Refresh meta nocache 2024-07-23 11:11:20 +02:00
Samuele Locatelli 1b1855c8f4 Commentato overlay 2024-07-23 11:10:47 +02:00
Samuele Locatelli 0aafcc6770 Merge tag 'FixSmartPwd01' into develop
Fix smart pwd x invio reset link
2024-07-23 11:06:14 +02:00
Samuele Locatelli f947f98e39 Merge branch 'release/FixSmartPwd01' 2024-07-23 11:06:04 +02:00
Samuele Locatelli 3ba140305e Fix recupero email x reset 2024-07-23 11:05:26 +02:00
Samuele Locatelli dcae718f75 Merge tag 'AddRobotCacheVeto02' into develop
Update x evitare reload con overlay (2 test)
2024-07-23 10:48:41 +02:00
Samuele Locatelli 921cbed53b Merge branch 'release/AddRobotCacheVeto02' 2024-07-23 10:48:31 +02:00
Samuele Locatelli dc43f4fe18 Test num2 gestione offline 2024-07-23 10:45:38 +02:00
Samuele Locatelli 76f7c0d05c Merge tag 'AddRobotCacheVeto01' into develop
Aggiunto veto cache (robot) da VALIDARE
2024-07-23 10:09:42 +02:00
Samuele Locatelli 4adda8deaf Merge branch 'release/AddRobotCacheVeto01' 2024-07-23 10:09:21 +02:00
Samuele Locatelli 236858e4dd COnf x evitare cache (forse) + fix gestione abse URI 2024-07-23 10:08:56 +02:00
Samuele Locatelli 2367b25c3c Merge tag 'FixEmailSendRev02' into develop
Aggiunto log x ogni invio email da API
2024-07-05 08:23:48 +02:00
Samuele Locatelli 840b27e452 Merge branch 'release/FixEmailSendRev02' 2024-07-05 08:23:13 +02:00
Samuele Locatelli 09cb7fd30c Update x log invio email GPW 2024-07-05 08:22:55 +02:00
Samuele Locatelli c53452bf98 Merge tag 'FixEmailSendRev0' into develop
Fix gestione conf email, tolto rev management e test, aggiunto chaimata
realmente async invio
2024-07-04 12:13:14 +02:00
Samuele Locatelli fd99bf78dd Merge branch 'release/FixEmailSendRev0' 2024-07-04 12:12:22 +02:00
Samuele Locatelli 9c0aa41620 FIX gestione conf password in reverse 2024-07-04 12:11:47 +02:00
Samuele Locatelli 01647b74b4 fix conf x email sender 2024-07-03 11:40:28 +02:00
Samuele Locatelli 573c967670 Merge tag 'AddCheckRegAtt02' into develop
Aggiunta Activity History
2024-07-02 17:51:09 +02:00
Samuele Locatelli 0c2b819fb3 Merge branch 'release/AddCheckRegAtt02' 2024-07-02 17:51:03 +02:00
Samuele Locatelli 1e0d2746c6 Update x visualizzazione ActivityHistory 2024-07-02 17:50:47 +02:00
Samuele Locatelli 60ed02f452 Merge tag 'AddCheckRegAtt01' into develop
Aggiunta check inizio/fine e periodi validità insert reg attività
2024-07-02 10:48:01 +02:00
Samuele Locatelli 0cbea6a055 Merge branch 'release/AddCheckRegAtt01' 2024-07-02 10:47:42 +02:00
Samuele Locatelli 0302aee0e8 Aggiunta criteri controllo validità periodo inizio/fine attività 2024-07-02 10:46:55 +02:00
Samuele Locatelli ba96677c80 Cambio colore sidebar x indicare modifiche 2024-07-02 08:34:24 +02:00
Samuele Locatelli fe42629e0e Merge tag 'FixAuthUrlKey02' into develop
Fix if/else url
2024-06-25 08:33:29 +02:00
Samuele Locatelli e2627ffb8d Merge branch 'release/FixAuthUrlKey02' 2024-06-25 08:32:12 +02:00
Samuele Locatelli 955ee08a45 Fix if/else jumper 2024-06-25 08:31:55 +02:00
Samuele Locatelli c0c3bd65e9 Merge tag 'FixAuthUrlKey' into develop
Fix chiave utente in URL x core smart
2024-06-25 08:07:10 +02:00
Samuele Locatelli c5a0d1595b Merge branch 'release/FixAuthUrlKey' 2024-06-25 08:07:00 +02:00
Samuele Locatelli d53a89b95e fix chaive old/new mancante 2024-06-25 08:06:36 +02:00
Samuele Locatelli 212b6abfef Fix ricerca chiave auth formato old/new x CORE SMART 2024-06-25 08:06:20 +02:00
Samuele Locatelli ed249951e2 Merge tag 'AddEmailToResp02' into develop
Fix typo codice idxResp da tab
2024-06-14 18:54:43 +02:00
Samuele Locatelli 9601eaffcd Merge branch 'release/AddEmailToResp02' 2024-06-14 18:54:22 +02:00
Samuele Locatelli d8db7a8075 Typo fix idx resp 2024-06-14 18:54:04 +02:00
Samuele Locatelli 7928ff14e2 Merge tag 'AddEmailToResp01' into develop
Aggiunta invio email al resp se non è approvatore principale
2024-06-14 18:48:59 +02:00
Samuele Locatelli a13bea1813 Merge branch 'release/AddEmailToResp01' 2024-06-14 18:48:48 +02:00
Samuele Locatelli ebd5af2d77 Aggiunta notifica al resp oltre che al l'approvatore 2024-06-14 18:48:25 +02:00
Samuele Locatelli 4fd374a4c3 Merge tag 'AddSearchRA01' into develop
Aggiunta ricerca attività su week + lista
2024-05-20 18:51:50 +02:00
Samuele Locatelli a59bb18c0e Merge branch 'release/AddSearchRA01' 2024-05-20 18:51:39 +02:00
Samuele Locatelli 3e2729f594 Fix search su lista attivita! 2024-05-20 18:51:05 +02:00
Samuele Locatelli 4f33831180 Aggiunto ricerca + highlight attività in RA 2024-05-20 17:00:53 +02:00
Samuele Locatelli 23f334d233 Merge tag 'AddFontDynResize02' into develop
Fine tuning dimensione fonts in caso di multi attività giornaliere
2024-04-16 16:21:25 +02:00
Samuele Locatelli c21532256d Merge branch 'release/AddFontDynResize02' 2024-04-16 16:21:09 +02:00
Samuele Locatelli 0d4fb29b5b Fix display dimensioni x multi-attività WRKLOG 2024-04-16 16:20:43 +02:00
Samuele Locatelli 10a1356a6e Merge tag 'AddFontDynResize01' into develop
Add font dyn resize x tante RA
2024-03-26 17:23:43 +01:00
Samuele Locatelli bf27ae8e19 Merge branch 'release/AddFontDynResize01' 2024-03-26 17:23:32 +01:00
Samuele Locatelli 041eae2260 Dyn resize chars x tanti RA 2024-03-26 17:22:42 +01:00
Samuele Locatelli c3f011ec75 Merge tag 'UseRedisSentinel01' into develop
Aggiunta gestione sentinel + install su IIS01/02/03 + test
2024-03-16 11:56:57 +01:00
Samuele Locatelli 9d05a9f068 Merge branch 'release/UseRedisSentinel01' 2024-03-16 11:56:41 +01:00
Samuele Locatelli 5b459bbd7b Fix passaggio sentinel da localhost 2024-03-16 11:56:29 +01:00
Samuele Locatelli 05ef3a3a4f cleanup cicd 2024-03-16 09:51:34 +01:00
Samuele Locatelli f1b5c99463 Update conf con server redis main/replica e sentinel 2024-03-16 09:48:19 +01:00
Samuele Locatelli 2f7337348e Update grafico detail Periodo (smaller) 2024-03-07 15:13:32 +01:00
Samuele Locatelli 7f88624935 Merge tag 'AddPresentStat02' into develop
Update comletato prima vers pag presenze
2024-03-07 10:38:18 +01:00
Samuele Locatelli dacd3b9bcd Merge branch 'release/AddPresentStat02' 2024-03-07 10:38:01 +01:00
Samuele Locatelli 596449f259 Completata review pag presenze 2024-03-07 10:37:46 +01:00
Samuele Locatelli e149445529 Update x display multi-user 2024-03-07 10:28:30 +01:00
Samuele Locatelli 178d7a3ef0 Update pag presenze 2024-03-05 18:47:24 +01:00
Samuele Locatelli 53d505006a Merge tag 'AddPresentStat01' into develop
Aggiunta info statistiche x admin
2024-03-05 17:16:27 +01:00
Samuele Locatelli 53e1abd2c0 Merge branch 'release/AddPresentStat01' 2024-03-05 17:16:18 +01:00
Samuele Locatelli 321b7a3a6f refresh orario 2024-03-05 17:16:05 +01:00
Samuele Locatelli 2e54c8b164 Update conf x admin gestito 2024-03-05 17:15:28 +01:00
Samuele Locatelli 8c978f68c2 Update display presenze 2024-03-05 16:27:34 +01:00
Samuele Locatelli 781c570a3d Bozza risposta a timbrature su PipeChannel 2024-03-05 10:31:16 +01:00
Samuele Locatelli de2a8cb6a5 Aggiunto invio su PipeChannel x timbrature e richieste 2024-03-05 10:30:54 +01:00
Samuele Locatelli 63e92f0c83 Merge tag 'TestReload03' into develop
Test reload senza boot.js
2024-03-05 08:30:48 +01:00
Samuele Locatelli 73a28e33b4 Merge branch 'release/TestReload03' 2024-03-05 08:30:40 +01:00
Samuele Locatelli f4d2265de2 Fix layout x GPW SMART 2024-03-05 08:30:25 +01:00
Samuele Locatelli b40764c2bc Merge tag 'TestReload02' into develop
Ancora update gestione reload pagina
2024-03-05 08:21:52 +01:00
Samuele Locatelli 0333154935 Merge branch 'release/TestReload02' 2024-03-05 08:21:41 +01:00
Samuele Locatelli fc19fb563e Update comportamento wrklog 2024-03-05 08:20:49 +01:00
Samuele Locatelli fd6a0512ba Merge tag 'TestReload_01' into develop
Update SMART
2024-03-01 19:08:26 +01:00
Samuele Locatelli 7c4ae1f7dc Merge branch 'release/TestReload_01' 2024-03-01 19:08:07 +01:00
Samuele Locatelli b9c2418532 Update SMART 2024-03-01 19:07:33 +01:00
Samuele Locatelli 50a6848f25 Merge tag 'TestReloadFooterWrklog_01' into develop
Update gestione footer WRKLOG
2024-02-28 16:15:12 +01:00
Samuele Locatelli 6e1b60cc71 Merge branch 'release/TestReloadFooterWrklog_01' 2024-02-28 16:14:36 +01:00
Samuele Locatelli 23a3985251 Update refresh WRKLOG 2024-02-28 16:14:04 +01:00
Samuele Locatelli 274d58ab68 typo 2024-02-27 15:42:59 +01:00
Samuele Locatelli 14637860e0 Merge tag 'UpdateLayoutReload01' into develop
Update layout + gestione placeholders vari
2024-02-27 15:34:34 +01:00
Samuele Locatelli fe0545084a Merge branch 'release/UpdateLayoutReload01' 2024-02-27 15:34:16 +01:00
Samuele Locatelli e37b5050e2 Update conf x reload + layout reloading 2024-02-27 15:32:04 +01:00
Samuele Locatelli fc3a6a70da Merge branch 'develop' 2024-02-24 12:09:35 +01:00
Samuele Locatelli 9837f276d7 update layout x smart 2024-02-24 12:09:27 +01:00
Samuele Locatelli 865aa0afab Merge tag 'FixReloadLayout03' into develop
Fix reload pagina (tenta x + tempo)
2024-02-24 11:58:53 +01:00
Samuele Locatelli ef2bd7c5d5 Merge branch 'release/FixReloadLayout03' 2024-02-24 11:58:41 +01:00
Samuele Locatelli 3c92333f0e Test altra modifica reload pagina 2024-02-24 11:58:19 +01:00
Samuele Locatelli 190b7a10b7 Merge tag 'FixReloadLayout02' into develop
Fix condizione reload + update pacchetti EgwCoreLib
2024-02-23 19:01:04 +01:00
Samuele Locatelli 7a89709a29 Merge branch 'release/FixReloadLayout02' 2024-02-23 19:00:46 +01:00
Samuele Locatelli 3777090416 Update librerie pacchetti EgwCoreLib e reload pagina 2024-02-23 19:00:23 +01:00
Samuele Locatelli 16d13748c9 Merge tag 'FixReloadLayout01' into develop
Fix condizioni reload layout
2024-02-19 19:33:24 +01:00
Samuele Locatelli 5a46df0f19 Merge branch 'release/FixReloadLayout01' 2024-02-19 19:33:14 +01:00
Samuele Locatelli d3ff540382 Update condizioni reload javascript 2024-02-19 19:32:56 +01:00
Samuele Locatelli 15fcbd57b9 Merge tag 'AddPageReconnectAuto' into develop
Aggiunto reconnect pagina
2024-02-19 09:15:55 +01:00
Samuele Locatelli 07ac5aa9a5 Merge branch 'release/AddPageReconnectAuto' 2024-02-19 09:15:45 +01:00
Samuele Locatelli 488ca47e50 Aggiunta clausola reconnect x evitare reload pagina 2024-02-19 09:15:05 +01:00
Samuele Locatelli b8af310248 Merge tag 'AddFerieSmartAndFixEmailNextYear' into develop
Aggiunto display ferie + fix invio email anno successivo
2023-12-07 08:26:50 +01:00
Samuele Locatelli dbfc7fddc4 Merge branch 'release/AddFerieSmartAndFixEmailNextYear' 2023-12-07 08:25:54 +01:00
Samuele Locatelli e6196db490 Aggiunto display ferie su smart 2023-12-07 08:25:16 +01:00
Samuele Locatelli 00e4a0158e Fix display richieste next year 2023-12-06 18:56:00 +01:00
Samuele Locatelli 838e0f6957 Merge tag 'FixTrimDomainUser01' into develop
Fix tab in campo DB x dominio
2023-11-08 11:36:06 +01:00
Samuele Locatelli b955c6e38e Merge branch 'release/FixTrimDomainUser01' 2023-11-08 11:35:55 +01:00
Samuele Locatelli 51eb178934 Fix check utente x errore \t (nascosto) 2023-11-08 11:35:31 +01:00
Samuele Locatelli bd6ef3d0ae Merge tag 'FixEmailGpwWrklog01' into develop
Fix email anche in GPW desktop/wrklog
2023-11-07 10:03:15 +01:00
Samuele Locatelli 6e13ebe8a9 Merge branch 'release/FixEmailGpwWrklog01' 2023-11-07 10:03:06 +01:00
Samuele Locatelli 25656f5eec Fix email in GPW desktop 2023-11-07 10:02:45 +01:00
Samuele Locatelli bc260f5de5 Merge tag 'FixEmailGpwSmart' into develop
Fix invio email da smart device
2023-11-07 09:57:08 +01:00
Samuele Locatelli 26507ae5bf Merge branch 'release/FixEmailGpwSmart' 2023-11-07 09:57:00 +01:00
Samuele Locatelli f3fb081103 Fix invio email x GPW SMART 2023-11-07 09:56:25 +01:00
Samuele Locatelli 3930a9e8dc Merge tag 'FixEmailrev01' into develop
Fix email reversed
2023-11-06 11:09:44 +01:00
Samuele Locatelli 09d1f42934 Merge branch 'release/FixEmailrev01' 2023-11-06 11:09:33 +01:00
Samuele Locatelli 394d924d1e Fix email pwd 2023-11-06 11:08:55 +01:00
Samuele Locatelli d2ad286f0f Merge tag 'AddResetAll01' into develop
Aggiunta pagina reset-all x forzare reset attivazioni licenze
2023-10-03 15:22:16 +02:00
Samuele Locatelli 4e1e958db0 Merge branch 'release/AddResetAll01' 2023-10-03 15:22:05 +02:00
Samuele Locatelli de09175f28 GPW-WRKLOG:
- Aggiunta pag reset nascosta ("reset-all")
2023-10-03 15:21:45 +02:00
Samuele Locatelli 2d009a76d8 Merge tag 'AddCheckTimbrFuture02' into develop
Fix testi log attività su DB
2023-09-01 07:39:50 +02:00
Samuele Locatelli 533452776d Merge branch 'release/AddCheckTimbrFuture02' 2023-09-01 07:39:12 +02:00
Samuele Locatelli 209fe7aa6c Correzione messaggi log check GPW 2023-09-01 07:38:18 +02:00
Samuele Locatelli da214155c0 Merge tag 'AddCheckTimbrFuture01' into develop
Gestione anomalia timbrature future: invio email!
2023-08-30 09:14:46 +02:00
Samuele Locatelli d36b60dc17 Merge branch 'release/AddCheckTimbrFuture01' 2023-08-30 09:14:32 +02:00
Samuele Locatelli 8527b91e6c Aggiunto step check anomalie timbrature future 2023-08-30 09:14:19 +02:00
Samuele Locatelli d345e84279 Merge tag 'UpdateEgwComp04' into develop
Update calcolo durate permessi/ferie
2023-07-31 18:46:10 +02:00
Samuele Locatelli 8bf47bb03b Merge branch 'release/UpdateEgwComp04' 2023-07-31 18:45:27 +02:00
Samuele Locatelli f1068e3f42 Fix calcolo durata fermi x WRKLOG e SMART 2023-07-31 18:44:49 +02:00
Samuele Locatelli c9c69f535a Merge tag 'UpdateEgwComp03' into develop
update componente progress loagding x pagine WRKLOG
2023-07-31 16:57:10 +02:00
Samuele Locatelli baecdd9c32 Merge branch 'release/UpdateEgwComp03' 2023-07-31 16:56:57 +02:00
Samuele Locatelli 56f0d36570 Update anche in WRKLOG dei componenti progress 2023-07-31 16:56:41 +02:00
Samuele Locatelli aa7ef25da9 Merge tag 'UpdateEgwComp02' into develop
Fix worklog x componenti nuget
2023-07-31 15:55:08 +02:00
Samuele Locatelli 75340443a2 Merge branch 'release/UpdateEgwComp02' 2023-07-31 15:54:54 +02:00
Samuele Locatelli 1eafdee5af Fix GPW.WRKLOG 2023-07-31 15:54:38 +02:00
Samuele Locatelli f9ea6f5721 Merge tag 'UpdateEgwComp01' into develop
update componenti EgwCore x loading + send email
2023-07-31 15:42:33 +02:00
Samuele Locatelli 3e363588e7 Merge branch 'release/UpdateEgwComp01' 2023-07-31 15:42:15 +02:00
Samuele Locatelli 94d2d46919 Update componenti EgwCore.Razor
- inseriti loader nuovi
- gestione progress bar(a) x invio email
2023-07-31 15:41:36 +02:00
Samuele Locatelli e6065535b4 Merge tag 'FixClonaPeriodo' into develop
Fix clona periodo x update
2023-07-03 08:41:51 +02:00
Samuele Locatelli 26110c9885 Merge branch 'release/FixClonaPeriodo' 2023-07-03 08:41:43 +02:00
Samuele Locatelli 38a9d7be73 Fix selezione periodo con clona 2023-07-03 08:41:22 +02:00
Samuele Locatelli b69ca54dcc Fix sel periodo free 2023-07-03 08:21:55 +02:00
Samuele Locatelli bd1c955f72 Merge tag 'UpdateHelp' into develop
Update help file
2023-06-30 12:18:43 +02:00
Samuele Locatelli a4947a95cd Merge branch 'release/UpdateHelp' 2023-06-30 12:18:33 +02:00
Samuele Locatelli 4b7f560e5a Update help file 2023-06-30 12:18:08 +02:00
Samuele Emilio Locatelli 69174bdb71 Merge branch 'develop' into 'main'
Develop

See merge request egalware-web/gest/gpw_next!1
2023-06-30 04:58:39 +00:00
Samuele Emilio Locatelli f10fbffaf5 Update MyRepStats.razor 2023-06-30 04:54:47 +00:00
Samuele Locatelli 8c5fa25801 Merge tag 'FixMyRepSize01' into develop
Sistemazione dimensione pagina MyReport x size e dimensioni caratteri
2023-06-29 19:13:04 +02:00
Samuele Locatelli e53daaf6a7 Merge branch 'release/FixMyRepSize01' 2023-06-29 19:12:50 +02:00
Samuele Locatelli 6e44e7cb56 Fix size dettaglio proj 2023-06-29 19:12:23 +02:00
Samuele Locatelli e2dccac335 MyReport:
- height max 42rem
2023-06-29 18:56:39 +02:00
Samuele Locatelli 27876c6530 Update altezza grafici 2023-06-29 18:23:59 +02:00
Samuele Locatelli 4c10c121e3 MyReport
Update layout FHD
2023-06-29 18:15:05 +02:00
Samuele Locatelli 0300ce6eac Fix display immagine 2023-06-29 18:05:10 +02:00
Samuele Locatelli 28ce9a3a1c Merge tag 'AddMyReportOnProd01' into develop
Aggiunta MyReport in prod
2023-06-29 17:05:55 +02:00
Samuele Locatelli fc9cb8d67a Merge branch 'release/AddMyReportOnProd01' 2023-06-29 17:05:37 +02:00
Samuele Locatelli 7d9d3ccbef Fix display vert + editing progetti 2023-06-29 16:35:18 +02:00
Samuele Locatelli 1dd4b4ae30 Ok inizio displ vert 2023-06-29 12:35:08 +02:00
Samuele Locatelli a5646aeabb Fix nuget x smart 2023-06-28 17:39:46 +02:00
Samuele Locatelli 00ed8fbf17 MyReport:
- Update compo
- default curr week analisi
2023-06-28 17:38:10 +02:00
Samuele Locatelli 1948fee63a Fix grafico 2023-06-28 17:19:23 +02:00
Samuele Locatelli ba0c0af831 Pagina Myreport Completa 2023-06-28 17:08:40 +02:00
Samuele Locatelli d2504e4fb6 ancora update calcoli report 2023-06-28 16:13:43 +02:00
Samuele Locatelli 5c674bf62d Prima bozza con recupero dati report... 2023-06-28 15:54:06 +02:00
Samuele Locatelli 7425be3e2a Aggiunta preliminare pagina MyReport + update EgwCoreLib 2023-06-28 14:56:16 +02:00
Samuele Locatelli 8cd48454a1 Merge tag 'ReviewLoginLicence01' into develop
Update x test gestione licenze dal 1° giorno nuovi dip
2023-06-12 14:30:18 +02:00
Samuele Locatelli f35edfb9db Merge branch 'release/ReviewLoginLicence01' 2023-06-12 14:30:05 +02:00
Samuele Locatelli 402442b8d2 Aggiunta delay e rilettura x licenza 2023-06-12 14:25:40 +02:00
Samuele Locatelli 10465fc7f3 Merge tag 'AddMaybeReconnectJScript06' into develop
rimesso riconnessione script
2023-06-09 11:06:47 +02:00
Samuele Locatelli 9a87d67b3d Merge branch 'release/AddMaybeReconnectJScript06' 2023-06-09 11:06:35 +02:00
Samuele Locatelli 473ce70f9a Redo gestione reload pagina 2023-06-09 11:06:12 +02:00
Samuele Locatelli 417fbe31c1 Merge tag 'AddMaybeReconnectJScript05' into develop
Fix compression resp
2023-06-08 19:03:34 +02:00
Samuele Locatelli 07e4ee2de1 Merge branch 'release/AddMaybeReconnectJScript05' 2023-06-08 19:03:27 +02:00
Samuele Locatelli 34db49f776 fix reload 2023-06-08 19:03:06 +02:00
Samuele Locatelli d7239dbf85 fix compressione response 2023-06-08 19:02:42 +02:00
Samuele Locatelli 0ad217bc54 Merge tag 'AddMaybeReconnectJScript04' into develop
Update ulteriore x riconnect
2023-06-08 19:00:18 +02:00
Samuele Locatelli 9f23e69505 Merge branch 'release/AddMaybeReconnectJScript04' 2023-06-08 18:59:57 +02:00
Samuele Locatelli 58df987e47 Modifica ulteriore riconnect 2023-06-08 18:59:40 +02:00
Samuele Locatelli ae615bf8d6 Merge tag 'AddMaybeReconnectJScript03' into develop
Update procedura riconnect
2023-06-08 18:54:23 +02:00
Samuele Locatelli 6e956330ea Merge branch 'release/AddMaybeReconnectJScript03' 2023-06-08 18:54:06 +02:00
Samuele Locatelli b75f501290 Fix riavvio (da testare) WRKLOG 2023-06-08 18:53:49 +02:00
Samuele Locatelli 69c8b7c97a Merge tag 'AddMaybeReconnectJScript02' into develop
Spostamento JScript in altra area (_Layout)
2023-06-08 18:07:39 +02:00
Samuele Locatelli 09a988ede9 Merge branch 'release/AddMaybeReconnectJScript02' 2023-06-08 18:07:26 +02:00
Samuele Locatelli 63943fa46d Spostamento JScript 2023-06-08 17:50:29 +02:00
Samuele Locatelli 762129bdd4 Merge tag 'AddMaybeReconnectJScript' into develop
Aggiunta JScript x tentare reconnect in caso di problemi
2023-06-08 17:38:05 +02:00
Samuele Locatelli 3cf826c048 Merge branch 'release/AddMaybeReconnectJScript' 2023-06-08 17:37:46 +02:00
Samuele Locatelli aa0b0f92e4 Aggiunto meccanismo (maybe) x reconnect di WRKLOG 2023-06-08 17:37:09 +02:00
Samuele Locatelli 10fc218d8b Merge tag 'UpdateWrkLogTimbMissingDate01' into develop
Aggiunta gestione missing date timbrature (gg passati...)
2023-05-23 16:27:28 +02:00
Samuele Locatelli a700a8752c Merge branch 'release/UpdateWrkLogTimbMissingDate01' 2023-05-23 16:27:06 +02:00
Samuele Locatelli 105cf4b756 vers refresh 2023-05-23 16:26:29 +02:00
Samuele Locatelli d46a0b731e Update x fix timbrature giorni prec + refresh 2023-05-23 16:26:24 +02:00
Samuele Locatelli b0df9f97b4 Merge tag 'AddCheckDoneOnTimb' into develop
Aggiunto check esecuzione timbratura prima di aggiornare
2023-05-11 08:30:03 +02:00
Samuele Locatelli 46c8023ab4 Merge branch 'release/AddCheckDoneOnTimb' 2023-05-11 08:29:30 +02:00
Samuele Locatelli 93c1b3b189 GPW CORE SMART:
-  controllo registrazione (effettiva) timbratura prima di update
2023-05-11 08:29:03 +02:00
Samuele Locatelli 9e66214f66 Merge tag 'AddMalattiaDaWrkLog' into develop
Aggiunta Malattia da WrkLog
2023-04-27 16:43:19 +02:00
Samuele Locatelli a4df2bba0d Merge branch 'release/AddMalattiaDaWrkLog' 2023-04-27 16:43:03 +02:00
Samuele Locatelli 705f2efd10 Update pubxml 2023-04-27 16:42:47 +02:00
Samuele Locatelli 22f49241e4 Aggiunta btn add malattia x WRKLOG 2023-04-27 16:41:42 +02:00
Samuele Locatelli c043486f82 Merge tag 'FixDisplayChiusuraAndWork' into develop
Sistemazione giornate con eventi ferie/fest + lavoro extra
2023-04-26 17:22:02 +02:00
Samuele Locatelli 5c30b30a27 Merge branch 'release/FixDisplayChiusuraAndWork' 2023-04-26 17:21:34 +02:00
Samuele Locatelli 3dc74caa98 Fix display giornate chiusura quando lavorate 2023-04-26 17:21:05 +02:00
Samuele Locatelli 384db1cdd0 Update display fest/ferie x day data 2023-04-26 17:03:35 +02:00
Samuele Locatelli 62b6c3a04d Merge tag 'UpdateSmartDisplCFF' into develop
Fix display CFF x home timb
2023-04-20 19:31:29 +02:00
Samuele Locatelli fa716e9f2f Merge branch 'release/UpdateSmartDisplCFF' 2023-04-20 19:30:06 +02:00
Samuele Locatelli 476487b3c0 Refresh colorazione fest/ferie (quadrato) + fix API 2023-04-20 19:29:41 +02:00
Samuele Locatelli 8899289d29 Aggiunta colorazione ferie/feste in SMART 2023-04-20 19:27:55 +02:00
Samuele Locatelli d8a0f5c453 Merge tag 'displayWeekCalRichMPF05' into develop
Fix colori x differenziare ferie/fest
2023-04-11 16:02:30 +02:00
Samuele Locatelli 4434cff466 Merge branch 'release/displayWeekCalRichMPF05' 2023-04-11 16:02:22 +02:00
Samuele Locatelli 87c42e0910 Fix colori diversi fest/ferie ufficio 2023-04-11 16:02:06 +02:00
Samuele Locatelli 34df9c59fb Merge branch 'main' into develop 2023-04-11 15:44:43 +02:00
Samuele Locatelli 1daeb227ea Merge tag 'displayWeekCalRichMPF04' into develop
Fix display permessi passati
2023-04-11 15:44:28 +02:00
Samuele Locatelli cac3f95895 Fix display permessi : se ho timb NON mostra 2023-04-11 15:44:16 +02:00
Samuele Locatelli 6a169705e6 Merge branch 'release/displayWeekCalRichMPF04' 2023-04-11 15:36:31 +02:00
Samuele Locatelli 584177e5c6 GPW.WRKLOG:
- review grafica indicazione feste/ferie
2023-04-11 14:41:23 +02:00
Samuele Locatelli 44ca4a4fd6 Merge tag 'displayWeekCalRichMPF03' into develop
Fix display richieste
2023-04-11 10:27:10 +02:00
Samuele Locatelli ead97b6863 Merge branch 'release/displayWeekCalRichMPF03' 2023-04-11 10:27:00 +02:00
Samuele Locatelli 5806f0619e Fix display attesa in cancellazione richieste 2023-04-11 10:26:47 +02:00
Samuele Locatelli 204ecb47b7 Merge tag 'displayWeekCalRichMPF02' into develop
Fix display ferie su + giorni / settimane
2023-04-11 10:09:03 +02:00
Samuele Locatelli 388aa0cd65 Merge branch 'release/displayWeekCalRichMPF02' 2023-04-11 10:08:39 +02:00
Samuele Locatelli f10c0d19c7 ancora fix ferie su cal week 2023-04-11 10:08:17 +02:00
Samuele Locatelli 9f105dd244 Fix calcolo ferie su + giorni x weekplan 2023-04-11 10:08:08 +02:00
Samuele Locatelli 59e2622e58 Merge tag 'displayWeekCalRichMPF' into develop
Fix display perm / fest / ferie su week cal personale
2023-04-11 09:11:11 +02:00
Samuele Locatelli 614ebcf818 Merge branch 'release/displayWeekCalRichMPF' 2023-04-11 09:10:56 +02:00
Samuele Locatelli b428ef59da Completata aggiunta indicaizone ferie/permessi futuri 2023-04-11 09:10:04 +02:00
Samuele Locatelli b4d2218f79 Inizio aggiunta festività, permessi, ferie in cal week 2023-04-11 08:42:04 +02:00
Samuele Locatelli ad6d4e9875 Merge tag 'FixWrkLogActionDisplay' into develop
Sistemazione posizione menù hover azioni in WRKLOG
2023-04-08 09:32:10 +02:00
Samuele Locatelli 6530664616 Merge branch 'release/FixWrkLogActionDisplay' 2023-04-08 09:31:51 +02:00
Samuele Locatelli ba0dc30c42 Fix display menù azioni WRKLOG 2023-04-08 09:31:19 +02:00
Samuele Locatelli 8d9f106a9a Merge tag 'FixDisplayFerieMultiDay' into develop
Fix display ferie multi-giorno
2023-04-03 10:42:25 +02:00
Samuele Locatelli f408c0e9d6 Merge branch 'release/FixDisplayFerieMultiDay' 2023-04-03 10:03:55 +02:00
Samuele Locatelli 81ad753268 Fix display ferie multi-giorno 2023-04-03 10:03:22 +02:00
Samuele Locatelli ed6bfd3b05 Merge tag 'FixQrcodeDisplayLink' into develop
Fix caratteri non ammessi x URL
2023-03-28 08:12:35 +02:00
Samuele Locatelli 2b7346063a Merge branch 'release/FixQrcodeDisplayLink' 2023-03-28 08:12:24 +02:00
Samuele Locatelli fa33bc9753 Fix QRCode
- auth da fare escaped x visualizzatore
2023-03-28 08:12:01 +02:00
Samuele Locatelli fff73423c2 Correzione commenti (minor) 2023-03-27 19:32:51 +02:00
Samuele Locatelli 0d159e76cc Merge tag 'FixnonAuthCheckPowershell' into develop
Fix gestione script powershell su pagine WRKLOG non auth che
rimablzavano controllo certificato
2023-03-24 19:34:58 +01:00
Samuele Locatelli 7e7393f42c Merge branch 'release/FixnonAuthCheckPowershell' 2023-03-24 19:34:39 +01:00
Samuele Locatelli 1d8a64fb2a Fix possibilità lancio non auth x check programma powershell 2023-03-24 19:34:08 +01:00
Samuele Locatelli c766ffeda3 Merge tag 'FixExtDeploy' into develop
Fix istruzioni deploy (MsDeploy era sbagliato)
2023-03-04 17:07:18 +01:00
Samuele Locatelli 86ded42bae Merge branch 'release/FixExtDeploy' 2023-03-04 17:07:07 +01:00
Samuele Locatelli 9c6733546f Fix deploy EXT:
- errato path x msdeploy sito esterno
2023-03-04 17:05:27 +01:00
Samuele Locatelli 201e092b21 Merge tag 'FixIntExtSiteSmart' into develop
Fix visualizzazione INT/EXT (testo + colore) x sito CORE SMART
2023-03-04 16:59:20 +01:00
Samuele Locatelli be122e6845 Merge branch 'release/FixIntExtSiteSmart' 2023-03-04 16:59:00 +01:00
Samuele Locatelli 512494aa38 CoreSmart:
- Fix calcolo INT/EXT
- display colore + testo home INT/EXT
2023-03-04 16:58:36 +01:00
Samuele Locatelli 1eb2d54235 fix deploy only main x develop 2023-03-04 15:01:01 +01:00
Samuele Locatelli de556ab2a8 Merge tag 'FixCiCdCore' into develop
Fix gestione deploy prod (da testare)
2023-03-04 15:00:17 +01:00
Samuele Locatelli 564a87e177 Merge branch 'release/FixCiCdCore' 2023-03-04 14:59:06 +01:00
Samuele Locatelli 140711eb39 Update dipendenze per problema pubblicazione update CORE 2023-03-04 12:23:43 +01:00
Samuele Locatelli eb280b9556 Merge tag 'fixProjBackup' into develop
Fix file inclusi
2023-03-03 19:32:19 +01:00
Samuele Locatelli 5341eae5ca Merge branch 'release/fixProjBackup' 2023-03-03 19:31:31 +01:00
Samuele Locatelli 2cd3882808 Merge tag 'UdateDeployIntExtOffice' into develop
Update pubblicazione GPW NEXT
2023-03-03 19:31:08 +01:00
Samuele Locatelli 10819e97f0 pulizia fiels 2023-03-03 19:29:02 +01:00
Samuele Locatelli 3ed1921d3d inizio fix conflitto versione 2023-03-03 19:26:55 +01:00
Samuele Locatelli 9ae0daa69e Merge branch 'release/UdateDeployIntExtOffice' 2023-03-03 19:25:17 +01:00
Samuele Locatelli f776112e5b ancora udpate pubblicazione GPW NEXT 2023-03-03 19:24:08 +01:00
Samuele Locatelli de9fc59637 Update principi pubblicazione siti 2023-03-03 19:23:57 +01:00
Samuele Locatelli 5e75d12a79 Merge tag 'AddGaugeAsButton' into develop
Aggiunta gauge come button
2023-02-17 09:47:28 +01:00
Samuele Locatelli 2fab9ede6e Merge branch 'release/AddGaugeAsButton' 2023-02-17 09:47:17 +01:00
Samuele Locatelli 7e1d1e464c Update componente gauge a button centrale 2023-02-17 09:46:48 +01:00
zaccaria.majid d548f0537c aggiunto pacchetto nuget 2023-02-03 10:00:46 +01:00
zaccaria.majid b91b473dbe fix libreria + aggiunto giorno corrente
calendario mfp
2023-02-03 09:15:07 +01:00
Samuele Locatelli 98a3f50771 Merge tag 'FixNewProdDb2019' into develop
Update stringhe conn DB PROD 2019
2023-02-02 16:19:22 +01:00
Samuele Locatelli 551991bc95 Merge branch 'release/FixNewProdDb2019' 2023-02-02 16:19:07 +01:00
Samuele Locatelli e561ccb2a7 Update GPW core x nuovo DB Prod 2023-02-02 16:18:32 +01:00
Samuele Locatelli 9f3eb7dde0 Merge tag 'AddNuPkgComp' into develop
iRImosso link proj comp + aggiunta nupkg
2023-02-02 16:03:33 +01:00
Samuele Locatelli 2a31fb9dcf Merge branch 'release/AddNuPkgComp' 2023-02-02 16:03:12 +01:00
Samuele Locatelli bdaaefb076 GPW CORE SMART:
- Rimozione proj comp
- inserito nupkg
2023-02-02 16:02:43 +01:00
Samuele Locatelli 74cde6035f Merge tag 'UpdateApiCheckTimbrature' into develop
Update API x timbrature
2023-01-27 11:44:04 +01:00
Samuele Locatelli 2507a9e35e Merge branch 'release/UpdateApiCheckTimbrature' 2023-01-27 11:43:55 +01:00
Samuele Locatelli d37766b3a3 GPW.Core.APi:
- update conf e test timb
2023-01-27 11:42:02 +01:00
Samuele Locatelli 3de47b92f2 Merge tag 'FixCheckTimb' into develop
fix modalità test timbrature (fallite stamattina)
2023-01-26 10:39:33 +01:00
Samuele Locatelli 81f9f4971e Merge branch 'release/FixCheckTimb' 2023-01-26 10:39:15 +01:00
Samuele Locatelli 7e3fc3e8f5 Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-26 10:38:50 +01:00
Samuele Locatelli 1e0486e7b5 Completati test x anomalie GPW 2023-01-26 10:38:42 +01:00
zaccaria.majid be357ff225 Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-26 08:30:52 +01:00
zaccaria.majid 8fff35405a aggiunto svg design grafico 2023-01-26 08:30:46 +01:00
Samuele Locatelli f7b482d36c Merge tag 'AddApiCheckTimbInProd' into develop
Update in prod x gestione check TImbrature
2023-01-25 19:01:45 +01:00
Samuele Locatelli a719be6195 Merge branch 'release/AddApiCheckTimbInProd' 2023-01-25 19:01:24 +01:00
Samuele Locatelli efeca5935d Merge branch 'release/AddApiCheckTimbInProd' into develop 2023-01-25 18:58:47 +01:00
Samuele Locatelli 6510fce274 Update cultureinfo x WRKLOG e API 2023-01-25 18:58:36 +01:00
Samuele Locatelli a0f30be0e3 Refresh 2023-01-25 18:56:31 +01:00
Samuele Locatelli 91a956ae60 Fix email admin 2023-01-25 18:54:04 +01:00
Samuele Locatelli 9d62995a70 Fix check controllo timbrature (da provare...) 2023-01-25 18:49:18 +01:00
Samuele Locatelli 8b85b4a2f8 OK primo check timbrature da approvare 2023-01-25 17:39:38 +01:00
Samuele Locatelli 619932b4c1 Aggiunta metodi recupero dati anomalie quotidiane 2023-01-25 15:35:50 +01:00
Samuele Locatelli b8429b1867 Update check timbrature (da completare) 2023-01-25 11:53:35 +01:00
Samuele Locatelli 88a260e88f Fix errore compilazione WrkLog 2023-01-25 11:36:47 +01:00
Samuele Locatelli 3dd5843ee5 Inizio aggiunta check timbrature ad API di GPW 2023-01-25 11:36:36 +01:00
Samuele Locatelli fd210e82d7 DB: gestione RegistroEventi 2023-01-25 11:36:05 +01:00
Samuele Locatelli 195ed3c157 Merge tag 'AddMonthNavigation' into develop
Update navigaizone mensile
2023-01-24 09:42:35 +01:00
Samuele Locatelli fb72e45e44 Merge branch 'release/AddMonthNavigation' 2023-01-24 09:42:08 +01:00
zaccaria.majid 4c1d7d7056 aggiunta visualizza multi-giorno ferie 2023-01-24 09:40:32 +01:00
zaccaria.majid d6b8d47dc7 Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-24 09:26:24 +01:00
zaccaria.majid 157fc77650 aggiunta cambio mese 2023-01-24 09:26:18 +01:00
Samuele Locatelli acd88fd0a4 Merge tag 'UpdateCUltureInfo' into develop
Tenbtativo update x gestione cultureinfo
2023-01-24 08:59:13 +01:00
Samuele Locatelli c2523ff0bc Merge branch 'release/UpdateCUltureInfo' 2023-01-24 08:58:53 +01:00
Samuele Locatelli c5d897919d update x cultureinfo 2023-01-24 08:58:23 +01:00
Samuele Locatelli 03ede3a967 Merge tag 'FixWrkLogReload' into develop
Fix rilettura WorkLog settimane precedenti
2023-01-23 19:29:39 +01:00
Samuele Locatelli 19f34abbec Merge branch 'release/FixWrkLogReload' 2023-01-23 19:29:28 +01:00
Samuele Locatelli 8b20f36c1b Errore WrkLog:
- Fix reload settimana corrente se edito precedenti
2023-01-23 19:29:06 +01:00
Samuele Locatelli 262d237f12 Merge tag 'TryFixNullNotePerm' into develop
Fix nullo su note permesso
2023-01-23 19:14:18 +01:00
Samuele Locatelli 3781031973 Merge branch 'release/TryFixNullNotePerm' 2023-01-23 19:14:11 +01:00
Samuele Locatelli ce2e409704 Aggiunti un paio di check sui valori null x malattie e permessi (2 test) 2023-01-23 19:13:44 +01:00
Samuele Locatelli 8fa92198f9 Merge tag 'fixCalClickDay' into develop
Fix click giorno da <span> a <td>
2023-01-23 11:10:04 +01:00
Samuele Locatelli 6a446c03e3 Merge branch 'release/fixCalClickDay' 2023-01-23 11:09:49 +01:00
Samuele Locatelli 81c7008771 Click calendario esteso:
- da <span> a intero <td>
2023-01-23 11:09:23 +01:00
Samuele Locatelli b1a8db2882 Merge tag 'FixDisposeGpwSmart' into develop
Update x disposable vari
2023-01-23 10:49:15 +01:00
Samuele Locatelli f64a7d3f3d Merge branch 'release/FixDisposeGpwSmart' 2023-01-23 10:40:31 +01:00
Samuele Locatelli 1580c939dd Update dispose vari in giro 2023-01-23 10:40:07 +01:00
Samuele Locatelli 899903aa5b Merge branch 'main' into develop 2023-01-23 07:58:28 +01:00
Samuele Emilio Locatelli 8516049343 Update .gitlab-ci.yml file x environment 2023-01-22 21:05:18 +00:00
Samuele E. Locatelli 7a13e99d69 Refresh 2023-01-22 21:45:18 +01:00
Samuele E. Locatelli f0d5c2a94a Update metodi lettura 2023-01-22 20:41:23 +01:00
Samuele E. Locatelli ec37691dff Merge tag 'FixAnimazione' into develop
Sistemata animazione
2023-01-22 20:16:00 +01:00
Samuele E. Locatelli 7c2033d1de Merge branch 'release/FixAnimazione' into main 2023-01-22 20:15:47 +01:00
Samuele E. Locatelli 8f403c0dee Correzioni Animazione 2023-01-22 20:14:50 +01:00
Samuele E. Locatelli 88b7f4b9b9 Merge branch 'develop' into main 2023-01-22 20:02:06 +01:00
Samuele E. Locatelli a45d6bcf6b Merge branch 'main' into develop 2023-01-22 20:01:59 +01:00
Samuele E. Locatelli a115517dde Cambio animazione NavBottom 2023-01-22 20:01:36 +01:00
Samuele E. Locatelli 26c21e48b3 Merge branch 'release/UpdateDeployCiCd' into main 2023-01-22 19:34:26 +01:00
Samuele E. Locatelli fc83cbf7ec Update CI/CD x deploy IIS02/IIS03 + nexus 2023-01-22 19:33:21 +01:00
Samuele E. Locatelli 94837e953e Fix effetto menù bottom 2023-01-22 19:31:24 +01:00
Samuele E. Locatelli 47a655c820 Update layout navbuttons 2023-01-22 19:17:41 +01:00
Samuele Locatelli 7fa1dbce3b Merge tag 'FixMenuBottom' into develop
Fix menù bottom
2023-01-22 15:35:07 +01:00
Samuele Locatelli f16541a066 Merge branch 'release/FixMenuBottom' 2023-01-22 15:34:58 +01:00
Samuele Locatelli f69c70b3b7 Semplificazione menu slide 2023-01-22 15:34:00 +01:00
Samuele Locatelli 4a1fbe591e Aggiunta versione + fix errore vers build 2023-01-22 14:55:34 +01:00
Samuele Locatelli 15a0bd295c typo WRKLOG 2023-01-22 14:53:14 +01:00
Samuele Locatelli af3d49cf4e Add about page 2023-01-22 14:52:56 +01:00
Samuele Locatelli 9b90a1b3ca fix top/botto 2023-01-22 14:52:43 +01:00
Samuele Locatelli 3feea9e514 Aggiunti profili pubb IIS02/03 2023-01-22 13:56:22 +01:00
Samuele Locatelli ce5d50209e Merge tag 'DeployProdSmart' into develop
Fix URL navigazione
2023-01-22 13:48:00 +01:00
Samuele Locatelli 9e7c7dea40 Merge branch 'release/DeployProdSmart' 2023-01-22 13:47:43 +01:00
Samuele Locatelli 3476cd79a4 Fix manc timb + link prod 2023-01-22 13:46:02 +01:00
Samuele Locatelli 6f7f676b01 Fix CHartJs display 2023-01-22 12:38:53 +01:00
Samuele Locatelli c3ea2126aa FIx grafici + test popup con toast x cal detail 2023-01-22 11:13:05 +01:00
Samuele Locatelli 591aada1e0 spostata posizione font 2023-01-22 11:10:06 +01:00
Samuele Locatelli 98df74fa0d Aggiunto componente toast 2023-01-22 11:09:57 +01:00
Samuele E. Locatelli (MBA) 8dfdb68a6a Merge branch 'main' into develop 2023-01-20 21:45:00 +01:00
Samuele E. Locatelli (MBA) 8f08d6457c Fix css calendario 2023-01-20 21:44:45 +01:00
Samuele Locatelli 9b96f7134b Merge tag 'ReleaseGpwSmartCore' into develop
Update in prod CoreSmart
2023-01-20 18:43:34 +01:00
Samuele Locatelli 520eb04d30 Merge branch 'release/ReleaseGpwSmartCore' 2023-01-20 18:43:16 +01:00
Samuele Locatelli cc308c05df Fix calendario 2023-01-20 18:33:01 +01:00
Samuele Locatelli 6ee87f4bce Fix reload permessi/ferie 2023-01-20 18:21:06 +01:00
Samuele Locatelli 131fb6ae15 Fix cambio sel settimana 2023-01-20 17:55:53 +01:00
Samuele Locatelli a78609b96d Fix chiusura dettaglio week 2023-01-20 17:44:51 +01:00
Samuele Locatelli fbd70decf5 Update display modale (parziale) 2023-01-20 17:19:10 +01:00
zaccaria.majid 84e4c086f4 Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-20 16:26:49 +01:00
zaccaria.majid 5b695ea7c5 fix grafici e inizio gestione click evento 2023-01-20 16:26:42 +01:00
Samuele Locatelli f2befdd90d Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-20 16:19:59 +01:00
Samuele Locatelli eaf63a3c72 Fix ricalcolo statistiche week x WRKLOG 2023-01-20 16:19:56 +01:00
zaccaria.majid 348cb21b0a fix slider 2023-01-20 14:46:18 +01:00
zaccaria.majid 137f8d601f fix colori calendario 2023-01-20 13:09:52 +01:00
Samuele Locatelli 9cc350da0c Minor fix selezione eventi replicati 2023-01-20 12:30:22 +01:00
Samuele Locatelli 40e666fa1b Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-20 12:07:15 +01:00
Samuele Locatelli c129b9640c Inizio fix dayOff first load 2023-01-20 12:07:12 +01:00
zaccaria.majid af65a73e27 aggiunto linking eventi 2023-01-20 12:06:19 +01:00
Samuele Locatelli c1d1c9746c Fix menù bottom 2023-01-20 12:05:00 +01:00
Samuele Locatelli dd8e5272a3 Update display cal week 2023-01-20 10:29:48 +01:00
Samuele Locatelli 65b22cbc65 Fix errore calEvent 2023-01-20 09:40:36 +01:00
zaccaria.majid 5f859bb317 fix larghezze viwebox 2023-01-20 09:27:27 +01:00
Samuele Locatelli 60fd732a8c Commit parziale componenti svg 2023-01-20 09:05:17 +01:00
Samuele Locatelli f345d804ab Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-19 19:13:20 +01:00
Samuele Locatelli f2e1d867e9 week calendar mostra qualcosina 2023-01-19 19:13:17 +01:00
zaccaria.majid 1789e9f40a aggiunta animazione dots 2023-01-19 18:06:51 +01:00
zaccaria.majid 537793cb8f gestione attività aggiornata 2023-01-19 17:43:18 +01:00
Samuele Locatelli a750376dba Fix calcolo label orarie 2023-01-19 17:32:03 +01:00
Samuele Locatelli a9798bd366 costruzione SIM eventi x cal 2023-01-19 16:28:35 +01:00
zaccaria.majid fc430a40af gestione x filtro settimanale attività 2023-01-19 15:27:56 +01:00
Samuele Locatelli 16e3a2d992 Ancora update x test calendario settimanale 2023-01-19 15:16:26 +01:00
zaccaria.majid 64701ff758 fix css x festività 2023-01-19 14:29:10 +01:00
Samuele Locatelli ba89ff0726 ok cambio settimana calendario 2023-01-19 12:59:48 +01:00
zaccaria.majid 708a907c05 Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-19 12:16:46 +01:00
zaccaria.majid c18ebd0f89 aggiunta gestione calendario con dot 2023-01-19 12:16:39 +01:00
Samuele Locatelli 8ff9385b67 Inizio bozza calendario settimanale 2023-01-19 11:06:19 +01:00
Samuele Locatelli eb6652699a Fix errore paste RA 2023-01-19 10:31:41 +01:00
Samuele Locatelli 220aaf21c0 Fixc errore compilazione x type blazorCal rimossi 2023-01-19 10:20:30 +01:00
Samuele Locatelli 19beb952bb Eliminazione calendario blazored 2023-01-19 10:18:42 +01:00
Samuele Locatelli 9a4bc648ee Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-19 10:03:05 +01:00
Samuele Locatelli 085540092a Fix gestione interno/esterno + arrotondamenti 2023-01-19 10:03:01 +01:00
zaccaria.majid 5e45bd2a69 pulizia files 2023-01-19 09:46:59 +01:00
zaccaria.majid e48481bdc0 fix fix grafici 2023-01-19 09:45:10 +01:00
Samuele Locatelli 4428eed168 Fix componente evento calendario 2023-01-19 09:21:25 +01:00
Samuele Locatelli 892603b956 Fix arrotondamenti :
- SMART
- WRKLOG
2023-01-19 08:42:50 +01:00
Samuele Locatelli 4c9b662e4c COmpilazione preliminare calendario richieste dip! 2023-01-18 19:33:18 +01:00
Samuele Locatelli 7a6f08343c fix calendario MPF: mostra feste + chiusure 2023-01-18 19:11:00 +01:00
Samuele Locatelli 11ddd5ae79 Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-18 18:54:16 +01:00
Samuele Locatelli 1fb4795549 Forzatura hideMenu 2023-01-18 18:53:56 +01:00
zaccaria.majid 818396c6d8 inizio gestione calendario dayoff 2023-01-18 17:19:46 +01:00
zaccaria.majid a3146a61cf fix controllo lista null 2023-01-18 15:59:54 +01:00
zaccaria.majid bda16699ab Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-18 15:55:10 +01:00
zaccaria.majid 21b32386d7 inizio calcolo colori ferie 2023-01-18 15:55:03 +01:00
Samuele Locatelli de448e95fc Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-18 15:54:17 +01:00
Samuele Locatelli 18d20707c0 Completato editing Richieste PERM/FERIE 2023-01-18 15:54:15 +01:00
zaccaria.majid cc60712fd2 Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-18 14:42:24 +01:00
zaccaria.majid aa236cfb5c fix animazione bottom + colore shadow 2023-01-18 14:41:35 +01:00
Samuele Locatelli 44125ad79d Ok display +
edit malattie
2023-01-18 14:27:42 +01:00
Samuele Locatelli 5a751ff4af Bozza pagina DayOff (MPF) 2023-01-18 14:11:08 +01:00
Samuele Locatelli fe2d31cfc5 Fix apertura index da btn navFooter 2023-01-18 13:57:35 +01:00
zaccaria.majid fa55eba725 Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-18 13:10:20 +01:00
zaccaria.majid 18d48ecaae fix grafici vari 2023-01-18 13:10:03 +01:00
Samuele Locatelli 5c9098e072 Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-18 12:09:08 +01:00
Samuele Locatelli a01153771b Aggiunta funzionalità delete 2023-01-18 12:09:05 +01:00
zaccaria.majid eae9f8f287 Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-18 11:57:52 +01:00
zaccaria.majid 1a8753abea pulizia menu 2023-01-18 11:57:46 +01:00
Samuele Locatelli fb413892a3 Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-18 11:51:45 +01:00
Samuele Locatelli 59560f927a Update gestione editing RA 2023-01-18 11:51:43 +01:00
zaccaria.majid b1c02d1483 Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-18 11:00:24 +01:00
zaccaria.majid d77d1603bc Nuova gestione menu 2023-01-18 11:00:16 +01:00
Samuele Locatelli 6b70c4be1d Fic errori spostamento TIMB 2023-01-18 10:38:19 +01:00
Samuele Locatelli f3fa19f96c cleanup modo calendario 2023-01-18 09:55:02 +01:00
Samuele Locatelli 13c09b4341 Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-18 09:54:44 +01:00
Samuele Locatelli 26cf47f6c7 Ok azione clona + update 2023-01-18 09:50:28 +01:00
zaccaria.majid 8e79305eac fix navigazione 2023-01-18 09:39:28 +01:00
Samuele Locatelli d88b0fac6f Pulizia metodi da step inutili 2023-01-18 08:45:56 +01:00
Samuele Locatelli 8d3a69afc1 Singolo componente x RA :
- clona
- display
2023-01-18 08:39:51 +01:00
Samuele Locatelli b00f5f26a6 OK CloneRA in memoria, da sistemare display + insert... 2023-01-17 21:07:02 +01:00
Samuele Locatelli 492d6fa9f4 Review grafica RA (effetto msussato 2023-01-17 19:58:11 +01:00
Samuele Locatelli df3f5e5625 Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-17 19:20:12 +01:00
Samuele Locatelli 2b48f19f92 Update x gestione delete e approva 2023-01-17 19:20:10 +01:00
Samuele Locatelli 223607f649 Fix gestione IP (solo su jumper) x tempi timbrature 2023-01-17 17:49:14 +01:00
zaccaria.majid 226459c819 Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-17 17:41:43 +01:00
zaccaria.majid c50452f441 fix grafico ore totali progetto 2023-01-17 17:41:37 +01:00
Samuele Locatelli 7cb2ad724c Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-17 17:23:35 +01:00
Samuele Locatelli 742bda00c1 Inizio modifica x gestione IPV4 e devName 2023-01-17 17:22:45 +01:00
zaccaria.majid b8073b5a73 aggiunto caricamento jumper 2023-01-17 17:02:48 +01:00
zaccaria.majid 5be8e2735e fix grafico prog 2023-01-17 17:00:29 +01:00
zaccaria.majid 6458f63c4a Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-17 16:22:07 +01:00
zaccaria.majid 1c9d19daf9 aggiunto comportamento giuto x prog 2023-01-17 16:21:59 +01:00
zaccaria.majid f332efba77 fix dtcard parametrica 2023-01-17 15:28:48 +01:00
Samuele Locatelli 74b4c06f75 Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-17 14:20:16 +01:00
Samuele Locatelli 605c68d3d5 Update conf x reload contenuto lista timbrature 2023-01-17 14:20:13 +01:00
zaccaria.majid 5166c4bc5e Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-17 13:25:07 +01:00
zaccaria.majid 54d9dade4b creata card x visualizzazione prog 2023-01-17 13:25:00 +01:00
Samuele Locatelli 83ab057286 Merge tag 'UpdateWrkLogSpacing' into develop
Aggiornamento spaziatura WrkLog: fix riordino record infa se lettura da
DB
2023-01-17 13:11:18 +01:00
Samuele Locatelli a197d61ddb Merge branch 'release/UpdateWrkLogSpacing' 2023-01-17 13:10:52 +01:00
Samuele Locatelli 074eaf343d GPW.Core.WRKLOG
- fix spaziatura x errato ordinamento record
2023-01-17 13:10:16 +01:00
Samuele Locatelli d85ede57c1 Eliminato cortocircuito sync/async 2023-01-17 12:34:15 +01:00
Samuele Locatelli 1162160350 Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-17 12:27:31 +01:00
Samuele Locatelli e72e975754 Update comportamento toast 2023-01-17 12:27:28 +01:00
zaccaria.majid 5cfc4bb865 fix errore compilazione 2023-01-17 12:25:25 +01:00
Samuele Locatelli 5dcbe3ed46 Test timbrature 2023-01-17 12:25:02 +01:00
zaccaria.majid 3e2160d64d Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-17 12:09:38 +01:00
zaccaria.majid e417edf727 aggiunti componenti per progetti 2023-01-17 12:09:08 +01:00
Samuele Locatelli 3b862aa03f Update con toast post timbrature 2023-01-17 11:51:01 +01:00
Samuele Locatelli 09581bd653 Update comportamento timbrature 2023-01-17 11:05:18 +01:00
Samuele Locatelli 44acbb9360 Fix errore update in cambio pagina 2023-01-17 09:03:50 +01:00
Samuele Locatelli 3bffd2b78c Fix salto a progetti + reload pagina 2023-01-17 08:23:30 +01:00
Samuele Locatelli 52c73973e6 Fix condizione reload x admin 2023-01-16 19:44:56 +01:00
Samuele Locatelli 80e4590abe Refresh grafico 2023-01-16 18:56:55 +01:00
Samuele Locatelli b1d0bbf780 Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-16 18:44:25 +01:00
Samuele Locatelli 8051a1adb3 Aggiunta link in bottom 2023-01-16 18:44:22 +01:00
zaccaria.majid b4562b6c83 Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-16 18:42:36 +01:00
zaccaria.majid 80febcc6cb cambio colore bg 2023-01-16 18:42:30 +01:00
Samuele Locatelli 18b4c113d1 Testo in timbr list parametrico 2023-01-16 18:39:05 +01:00
Samuele Locatelli 1a324a1cd9 aggiunta brutale admin 2023-01-16 18:32:14 +01:00
Samuele Locatelli f4e02e6f6f Update link QR x multiplot 2023-01-16 18:29:38 +01:00
Samuele Locatelli 11702db3e5 Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-16 18:18:03 +01:00
Samuele Locatelli b8d4bd1a65 Aggiunta QR x dipendente 2023-01-16 18:18:00 +01:00
zaccaria.majid 26a97ed6ec aggiunta gestione mancate timbrature 2023-01-16 17:54:06 +01:00
Samuele Locatelli c33927fd93 Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-16 17:31:19 +01:00
Samuele Locatelli f73891da9e Check Aggiunta componente timbr user 2023-01-16 17:31:17 +01:00
zaccaria.majid 9a2f0a2fb8 Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-16 17:08:51 +01:00
zaccaria.majid 59092a472b gestione click gauge ore lavorate 2023-01-16 17:08:45 +01:00
Samuele Locatelli 3d24578a3b Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-16 16:43:09 +01:00
Samuele Locatelli ff0b84042c Timbrature:
- OK approvazione
- OK scambio IN/OUT
- OK eliminazione
2023-01-16 16:43:03 +01:00
zaccaria.majid b43d849f3e Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-16 16:10:09 +01:00
zaccaria.majid 9b382867f6 aggiunta funzione mancata timbratura
+ aggiornamento grafico
2023-01-16 16:10:01 +01:00
Samuele Locatelli e694553f89 Aggiunto gestione reset authKey x admin 2023-01-16 14:30:38 +01:00
Samuele Locatelli ce30ca1eba Sposstato toggler in componenti 2023-01-16 14:30:31 +01:00
Samuele Locatelli b604046a2c Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-16 12:19:54 +01:00
Samuele Locatelli 7713465e00 Correzione authKey x encoding URL 2023-01-16 12:19:46 +01:00
zaccaria.majid b549ef07a4 Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-16 11:39:49 +01:00
zaccaria.majid 206f5e9bc4 fix scrittura diversi colori per mancate timbrature 2023-01-16 11:39:42 +01:00
Samuele Locatelli a6b8eeff5d Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-16 11:37:49 +01:00
Samuele Locatelli ee36394b3d Test invio email 2023-01-16 11:37:46 +01:00
Samuele Locatelli 3dd6ac1018 Update metodo x mancate timbrature 2023-01-16 11:37:21 +01:00
zaccaria.majid 5a62abbdb0 Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-16 09:39:36 +01:00
zaccaria.majid 6cb0544754 aggiornamento grafico 2023-01-16 09:39:27 +01:00
Samuele Locatelli a83ff37995 Fix calcolo orario live 2023-01-16 09:38:42 +01:00
Samuele Locatelli 259679c178 tentativo toast (NO way) 2023-01-16 09:10:54 +01:00
Samuele Locatelli ce176cd47e FIx vari display 2023-01-16 08:35:32 +01:00
Samuele Locatelli a781bbf6ff Update conf favicon 2023-01-14 12:48:10 +01:00
Samuele Locatelli 84d40f830c Inizio creazione apgine supporto/recupero 2023-01-14 11:13:30 +01:00
Samuele Locatelli 4902065f0a Ulteriore modifica x fix hostname calc 2023-01-14 10:21:10 +01:00
Samuele Locatelli ccc02a48b3 Rimosso problema GetDns x app 2023-01-14 10:16:46 +01:00
Samuele Locatelli f5c764eafb SMART:
- Update link reload (da testare)
- update colore in reload
2023-01-14 10:07:25 +01:00
Samuele Locatelli a9ac7f284f Calendario:
- Rimessi metodi necessari a modifiche Zac
- code refactor
2023-01-13 19:28:41 +01:00
Samuele Locatelli baa6a84ad5 cleanup 2023-01-13 19:24:45 +01:00
Samuele Locatelli e2778a51ec Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-13 19:21:04 +01:00
Samuele Locatelli a0c831af95 Cache su server gestione dei dati di devSecrets 2023-01-13 19:18:18 +01:00
Samuele Locatelli 37ae849c93 Completato update e pulizia x gestione IP da solo Blazor 2023-01-13 19:06:32 +01:00
Samuele Locatelli 062b3fa556 Modifica x gestione checkIp tutto in blazor (NO JS) 2023-01-13 19:01:22 +01:00
Samuele Locatelli cea53a124c Fix comportamento display a cascata 2023-01-13 18:47:41 +01:00
zaccaria.majid 796679f91b Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-13 17:23:23 +01:00
zaccaria.majid bf9241aacb Aggiunta modalità calcolo timbratura approvata 2023-01-13 17:22:44 +01:00
Samuele Locatelli a18011e45d Inizio spostsamento lettura dati tra componenti Smart 2023-01-13 17:20:34 +01:00
Samuele Locatelli a2154c0b84 Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-13 14:34:20 +01:00
Samuele Locatelli 5f06c38bf5 UPdate comportamento timbratura 2023-01-13 14:34:16 +01:00
zaccaria.majid 4307e6fe42 Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-13 12:53:51 +01:00
zaccaria.majid ad8fbf4852 continuo calendario 2023-01-13 12:53:44 +01:00
Samuele Locatelli 0e71534de7 Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-13 12:29:39 +01:00
Samuele Locatelli 3705bf6e5f inizio gestione nextIsEntrata 2023-01-13 12:29:36 +01:00
zaccaria.majid 6a4dff3386 Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-13 11:40:50 +01:00
zaccaria.majid 41f65df85d aggiornamento grafico 2023-01-13 11:40:36 +01:00
Samuele Locatelli c460b5fb77 Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-13 11:39:13 +01:00
Samuele Locatelli 88ab08e4b8 Fix colore display post azione 2023-01-13 11:39:10 +01:00
Samuele Locatelli e39e62e4cc update secondi che pulsano 2023-01-13 11:36:05 +01:00
zaccaria.majid 495885a2be Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-13 11:27:50 +01:00
zaccaria.majid ac26e1fc37 grafica componente calendario 2023-01-13 11:27:43 +01:00
Samuele Locatelli 9c089aad42 Update x lib bootstrap 2023-01-13 11:27:26 +01:00
Samuele Locatelli 9843c061e6 Fix display entrata/uscita con pulse 2023-01-13 11:05:15 +01:00
Samuele Locatelli df91add2f3 Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-13 10:10:55 +01:00
Samuele Locatelli 96c430abd3 Fix update stato buttons x entrata/uscita 2023-01-13 10:10:24 +01:00
zaccaria.majid 23caf99c91 inizio gestione mancate timbrature 2023-01-13 09:47:13 +01:00
Samuele Locatelli 3f94ad59de Fiox btn 2023-01-13 08:28:10 +01:00
Samuele Locatelli 28296cb22a Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-13 08:26:58 +01:00
Samuele Locatelli f482e53a84 Fix tempRil e reset 2023-01-13 08:26:54 +01:00
zaccaria.majid 821b82d242 Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-12 18:32:08 +01:00
zaccaria.majid 235a074147 bozza modale 2023-01-12 18:32:02 +01:00
Samuele Locatelli 9781967c4a Fix WRKLOG: scambio sempre possibile 2023-01-12 17:43:33 +01:00
Samuele Locatelli 6789a29661 Fix timb <--> rilTemp 2023-01-12 17:39:49 +01:00
Samuele Locatelli 1afd110487 Update x gestione pagina grafici temp 2023-01-12 17:31:36 +01:00
Samuele Locatelli 22e2141cf3 Completato spostamento grafici temperatura 2023-01-12 17:08:33 +01:00
Samuele Locatelli 896d2fbb12 Spostato grafici in area componenti condivisi 2023-01-12 16:59:45 +01:00
Samuele Locatelli 2dc27d3917 codemaid GpwDataService 2023-01-12 16:35:36 +01:00
Samuele Locatelli 231fb1209b inizio udpate data adapter core smart 2023-01-12 16:34:48 +01:00
Samuele Locatelli 5d31b10f75 Update WRKLOG x inclusione componenti base 2023-01-12 16:34:40 +01:00
Samuele Locatelli eb37fa4d0d refresh componenti 2023-01-12 16:16:53 +01:00
Samuele Locatelli 35d7fea84b Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-12 15:59:35 +01:00
Samuele Locatelli 319680a974 Tolto idx utente da session storage 2023-01-12 15:58:11 +01:00
zaccaria.majid dfa0806326 divisione code behind regnewdev 2023-01-12 15:33:47 +01:00
Samuele Locatelli 5d635662c8 Aggiunta procedura logout 2023-01-12 13:04:54 +01:00
Samuele Locatelli 1b88196574 Recupero IP OK 2023-01-12 12:54:28 +01:00
Samuele Locatelli 8fd0c430f9 update con segnaposto pagine necessarie 2023-01-12 12:28:43 +01:00
Samuele Locatelli b8ea6f5c7a Completata gestione login/jumper/checkUser 2023-01-12 12:15:14 +01:00
Samuele Locatelli f82e8a6506 Update login con jumper OK... 2023-01-12 11:38:25 +01:00
zaccaria.majid e4d3726203 fix force reload 2023-01-12 09:22:45 +01:00
zaccaria.majid ffffb7ce63 Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-11 17:31:15 +01:00
zaccaria.majid 9eed839919 continuo login
con jumper
2023-01-11 17:30:17 +01:00
Samuele Locatelli f523b19968 Merge branch 'develop' 2023-01-11 14:19:46 +01:00
Samuele Locatelli 41de920ac3 Fix nuget blazored + componente top 2023-01-11 14:19:19 +01:00
Samuele Locatelli df00a96295 Merge tag 'FixDeviceUpsert' into develop
Fix metodo scrittura upsert
2023-01-11 14:15:54 +01:00
Samuele Locatelli d53ec5e37c Merge branch 'hotfix/FixDeviceUpsert' 2023-01-11 14:15:48 +01:00
Samuele Locatelli 90683eb2ca Merge branch 'develop' into hotfix/FixDeviceUpsert 2023-01-11 14:15:39 +01:00
Samuele Locatelli ca49ba4065 Fix scrittura upsert device 2023-01-11 14:15:18 +01:00
Samuele Locatelli 5a24e4f6b4 Merge tag 'FixWrkLogRedis' into develop
Fix Redis cache x WrkLog
2023-01-11 14:12:46 +01:00
Samuele Locatelli 100a0ee759 Merge branch 'release/FixWrkLogRedis' 2023-01-11 14:12:33 +01:00
zaccaria.majid f09f8ab566 Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-11 12:21:16 +01:00
zaccaria.majid 825622144e aggiunto local service 2023-01-11 12:21:11 +01:00
Samuele Locatelli 8e6e3b55f4 Aggiunto controller dati x AnagDevices 2023-01-11 12:08:49 +01:00
Samuele Locatelli bda4ea12a2 Merge remote-tracking branch 'origin/develop' into develop 2023-01-11 11:45:07 +01:00
zaccaria.majid b408719b53 bozza colore today 2023-01-11 11:41:41 +01:00
zaccaria.majid a8147d257c Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-11 11:28:54 +01:00
zaccaria.majid 347aa867c0 fix grafici 2023-01-11 11:28:42 +01:00
Samuele Locatelli 5c670365ec TypoFix 2023-01-11 11:28:37 +01:00
Samuele Locatelli 7c74090eb3 Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-11 11:07:23 +01:00
Samuele Locatelli 1a90e4b729 Completato switch cache x WRKLOG 2023-01-11 11:07:20 +01:00
zaccaria.majid f88e5e3d07 prova drag 2023-01-11 10:26:24 +01:00
Samuele Locatelli 2a0c8d09d4 Fix Display Smart 2023-01-11 09:51:49 +01:00
Samuele Locatelli f13e712470 Ok colore date 2023-01-11 09:47:02 +01:00
Samuele Locatelli e7d100e7d3 Fix round tempi 2023-01-11 09:38:05 +01:00
Samuele Locatelli 0973c677a1 Update grafica OK x calendario 2023-01-11 09:25:16 +01:00
Samuele Locatelli 9b91c95369 Update smart x componenti e gest calendario(start) 2023-01-11 09:16:30 +01:00
Samuele Locatelli 15c2733e0e Eliminaizone comp da libreria --> Smart 2023-01-11 09:16:20 +01:00
Samuele Locatelli 19a015e072 Ancora cache fix x WrkLog 2023-01-11 09:16:06 +01:00
Samuele Locatelli e77c7b3c7f Continuo fix dati x cambio tipologia cache 2023-01-11 07:58:41 +01:00
Samuele Locatelli 882ca626de Ancora update cache worklog 2023-01-10 21:01:33 +01:00
Samuele Locatelli 4c87399a32 Update lettura dati x SMART 2023-01-10 20:48:34 +01:00
Samuele Locatelli b18820ce02 Prima gestione con redis cache NewtonSoft 2023-01-10 20:48:28 +01:00
Samuele Locatelli d91455492e eliminato riferimento circolare clienti da progetti 2023-01-10 20:48:01 +01:00
zaccaria.majid 9357519813 fix lettura da db 2023-01-10 18:40:55 +01:00
Samuele Locatelli 23886b4109 Aggiunta preliminare script x versNumb 2023-01-10 18:18:00 +01:00
Samuele Locatelli 44f9414f0d Fix compilazione SMART 2023-01-10 18:17:47 +01:00
Samuele Locatelli 18865fa274 Fix core data service 2023-01-10 17:58:11 +01:00
Samuele Locatelli a65b47623d Merge remote-tracking branch 'origin/develop' into develop 2023-01-10 17:56:55 +01:00
Samuele Locatelli 0df42a5dce Merge remote-tracking branch 'origin/develop' into develop 2023-01-10 17:52:24 +01:00
Samuele Locatelli 0ebd0133c9 Test modifica avvio cache redis 2023-01-10 17:50:35 +01:00
zaccaria.majid 34471c6073 Bozza lettura dati 2023-01-10 17:46:57 +01:00
Samuele Locatelli 405d73c3c7 Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-10 17:26:44 +01:00
Samuele Locatelli 932e9a75dd Fix redis flush cache 2023-01-10 17:26:42 +01:00
zaccaria.majid a28c0fbac5 Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-10 17:18:48 +01:00
zaccaria.majid 982aace898 aggiunta libreria font awesome +
inizio pagina timbratura
2023-01-10 17:18:40 +01:00
Samuele Locatelli 9faefb3746 Aggiunta recupero dati DailyDTO (da testare!) 2023-01-10 17:15:15 +01:00
Samuele Locatelli 31c17016bd Update CI-CD 2023-01-10 16:35:15 +01:00
Samuele Locatelli 6882f43733 Typo CI/CD 2023-01-10 15:19:47 +01:00
Samuele Locatelli 812023ae42 refresh params x deploy 2023-01-10 15:19:03 +01:00
Samuele Locatelli 515ee06c00 Aggiunta CI-CD x deploy 2023-01-10 15:18:56 +01:00
Samuele Locatelli 60c1de1e38 Bozza metodoa ccesso dati 2023-01-10 14:59:17 +01:00
Samuele Locatelli fcc13c4fba Fix SMART 2023-01-10 14:51:36 +01:00
zaccaria.majid 50b8753a1a Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-10 14:42:52 +01:00
zaccaria.majid 9c8ec35bfd fix gpw smart 2023-01-10 14:42:44 +01:00
zaccaria.majid e2508984a2 modifiche calendario e aggiunta comportamento bottom 2023-01-10 14:33:14 +01:00
Samuele Locatelli 282c03abcc Merge tag 'UnificazioneOrePermessi' into develop
Unificazione ore permessi + fix vari componenti libreria nuova
2023-01-10 12:15:35 +01:00
Samuele Locatelli 81466594c8 Merge branch 'release/UnificazioneOrePermessi' 2023-01-10 12:15:14 +01:00
Samuele Locatelli cc8495f211 Fix gauge SVG 2023-01-10 10:12:01 +01:00
Samuele Locatelli 1ce55c272b Fix gauge totalmente svg parametrico 2023-01-10 09:49:50 +01:00
Samuele Locatelli 972c781548 Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-09 19:30:47 +01:00
Samuele Locatelli a8a9b88d89 CORE.WrkLog:
- unificazione Malattie con altri pemessi
2023-01-09 19:30:43 +01:00
zaccaria.majid 54b7dbb1c6 fix centratura calendario 2023-01-09 18:36:54 +01:00
zaccaria.majid 6ea98758ac Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-09 18:10:57 +01:00
zaccaria.majid 079da2b384 fix grafico calendario 2023-01-09 18:10:46 +01:00
Samuele Locatelli a5529352ad Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-09 17:13:07 +01:00
Samuele Locatelli 21a51fed05 minor fix footer tabella 2023-01-09 17:13:04 +01:00
zaccaria.majid 2296ecf5b0 Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-09 17:11:46 +01:00
zaccaria.majid aa2d400e8d fix grafico 2023-01-09 17:11:17 +01:00
Samuele Locatelli 8750d354b0 Fix spostamenti orizzontali in sel vista calendario 2023-01-09 17:08:48 +01:00
Samuele Locatelli ba9491220c FIx display singola riga calendario 2023-01-09 17:01:41 +01:00
Samuele Locatelli 6efa1c6dcb Fix display calendario con icone rounded 2023-01-09 16:38:05 +01:00
zaccaria.majid 28e1dac334 Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-09 15:59:38 +01:00
zaccaria.majid e5e47a3e88 aggiunti componenti bottm e top 2023-01-09 15:59:31 +01:00
Samuele Locatelli 1e2a09a469 Prima demo componente table mese 2023-01-09 15:54:17 +01:00
zaccaria.majid 2ef42fefd5 aggiunta card data +
aggiunta bottoni entrata uscita +
style gauge
2023-01-09 14:53:59 +01:00
Samuele Locatelli c8cd8f090c Aggiunto mixin x less calss 2023-01-09 12:42:33 +01:00
Samuele Locatelli 33055e045d Update display gauge 2023-01-09 12:37:08 +01:00
Samuele Locatelli 60793c02a5 Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop 2023-01-09 12:03:55 +01:00
Samuele Locatelli 17dfe8fc8a Inizio gestione mese 2023-01-09 12:03:52 +01:00
zaccaria.majid 8055de2e9c fix percentuali gauge 2023-01-09 12:03:21 +01:00
Samuele Locatelli b8609a3917 Aggiunta classe component library 2023-01-09 09:38:35 +01:00
Samuele Locatelli 6142f938bd Merge remote-tracking branch 'origin/NewSmartGPW' into develop 2023-01-09 08:21:42 +01:00
Samuele Locatelli f24cd46b6b Merge branch 'main' into develop 2023-01-05 20:33:46 +01:00
Samuele Locatelli ed5f69f576 Merge tag 'FixSelDatePErm' into develop
Fix seelzione date
2023-01-05 20:33:38 +01:00
Samuele Locatelli ce1d6f0cc8 Fix messaggio wait insert/delete permessi e insert malattie 2023-01-05 20:33:24 +01:00
Samuele Locatelli 2bd0f71785 Fix invio email permessi 2023-01-05 18:45:29 +01:00
Samuele Locatelli e6c03a18d2 Merge branch 'release/FixSelDatePErm' 2023-01-05 15:42:30 +01:00
Samuele Locatelli 78ea1c7ff9 Fix periodo sel date 2023-01-05 15:40:29 +01:00
Samuele Locatelli ff970b2519 Merge branch 'main' into develop 2023-01-05 14:56:00 +01:00
Samuele Locatelli fe9af25bfb Merge tag 'FixDatiAltrui' into develop
Fix grafici e reload malattie
2023-01-05 14:55:53 +01:00
Samuele Locatelli 6e4e76262b Merge branch 'develop' 2023-01-05 14:55:42 +01:00
Samuele Locatelli 86bfadb725 Merge branch 'release/FixDatiAltrui' 2023-01-05 14:55:33 +01:00
Samuele Locatelli 894882caf7 refresh librerie 2023-01-05 14:55:23 +01:00
Samuele Locatelli 060dbd9ac9 Minor fix grafici 2023-01-05 14:18:40 +01:00
Samuele Locatelli 5becae35af Redo fix toggler 2023-01-05 14:04:39 +01:00
Samuele Locatelli 544ff232a9 Fix reload malattie altrui! 2023-01-05 14:01:16 +01:00
Samuele Locatelli 980dbfd45c MaybeFix Malattie 2023-01-05 10:59:22 +01:00
Samuele Locatelli 4f6d38e1ce Fix display malattie non proprie 2023-01-05 10:51:57 +01:00
Samuele Locatelli 9d4282c899 Merge branch 'main' into develop 2023-01-05 10:32:57 +01:00
Samuele Locatelli 0eece9d283 Merge tag 'UpdateBootstrap5' into develop
Update bootstrap 5
2023-01-05 10:32:44 +01:00
Samuele Locatelli 95faf82065 Aggiunta permessi altrui 2023-01-05 10:32:41 +01:00
Samuele Locatelli 02aabeb07e Merge branch 'release/UpdateBootstrap5' 2023-01-05 10:26:09 +01:00
Samuele Locatelli f378470c0b Completata review generale x bootstrap 5 ! 2023-01-05 10:25:42 +01:00
Samuele Locatelli 7fcc248ddf Update lib bootstrap 4-->5 2023-01-05 10:12:36 +01:00
Samuele Locatelli c32571dc47 Bozza toggler 2023-01-05 06:51:23 +01:00
Samuele Locatelli e00e0ec939 Fix display selettore 2023-01-04 19:19:19 +01:00
Samuele Locatelli 3ae367bb10 Merge tag 'AddMonthSel' into develop
Fix selezione multimese/singolo mese
2023-01-04 19:12:03 +01:00
Samuele Locatelli 78db63442f Merge branch 'release/AddMonthSel' 2023-01-04 19:11:48 +01:00
Samuele Locatelli 2fe59376a1 Fix sel mese 2023-01-04 19:11:07 +01:00
Samuele Locatelli c27534ee93 Aggiunta toggle modo calendario 2023-01-04 19:04:44 +01:00
Samuele Locatelli 8bd62b9ab0 Merge remote-tracking branch 'origin/main' into develop 2023-01-04 15:10:32 +01:00
Samuele Locatelli df8255447c Tolti commenti 2023-01-04 15:09:57 +01:00
Samuele Locatelli 59f13afcd2 Display permessi solo x singolo utente 2023-01-03 16:30:42 +01:00
Samuele Locatelli 0bc73851e1 GPW_NEXT:
- completata prima release gestione permessi/ferie/malattie
2023-01-03 16:15:55 +01:00
Samuele Locatelli d643e9e0be Ancora update gestione richieste con causali corrette 2023-01-03 12:09:42 +01:00
Samuele Locatelli a583e8b9e8 Prima gestione richeiste perm/fer/104 2023-01-03 11:52:25 +01:00
Samuele Locatelli e20835878c Typo! 2023-01-03 08:00:50 +01:00
Samuele Locatelli 07085d3260 Nascosto appunti x "non Sam" 2023-01-03 07:57:17 +01:00
Samuele Locatelli bec80c135e Aggiunta preliminare calendario dettagli chiusure ufficio 2023-01-02 19:15:51 +01:00
Samuele Locatelli 31d18243e9 Gestione email inserimento/eliminazione malattia 2023-01-02 17:10:20 +01:00
Samuele Locatelli d7bfb7a5d1 Update pagina malattia (OK lato utente) 2023-01-02 16:43:23 +01:00
Samuele Locatelli b6c6194da3 NavMenu (preliminare) 2023-01-02 14:44:50 +01:00
Samuele Locatelli a9a4b371d2 Aggiunta preliminare appunti 2023-01-02 14:44:37 +01:00
Samuele Locatelli 030fba6462 Aggiunta modello x RegMalattie 2023-01-02 14:44:28 +01:00
Samuele Locatelli a92c9c4694 Merge tag 'AddTaskFromListPage' into develop
Aggiunta funzionalità clona/delete in lista attività
2022-10-14 16:48:28 +02:00
3488 changed files with 1050175 additions and 60379 deletions
+219 -49
View File
@@ -1,6 +1,8 @@
variables:
VERS_MAIN: '2.9'
VERS_MAIN: '3.0'
NEW_REL: ''
APP_NAME: 'GPW.App'
SOL_NAME: 'GPW.APP'
# helper x fix pacchetti nuget da repo locale nexus.steamware.net
.nuget-fix: &nuget-fix
@@ -9,19 +11,56 @@ variables:
dotnet nuget list source
$hasSource = dotnet nuget list source | Select-String -Pattern "Steamware Nexus Proxy"
if (! [String]::IsNullOrWhiteSpace($hasSource)) {
dotnet nuget remove source "`"Steamware Nexus Proxy`""
dotnet nuget remove source "Steamware Nexus Proxy"
}
$hasSource = dotnet nuget list source | Select-String -Pattern "Steamware Nexus"
if (! [String]::IsNullOrWhiteSpace($hasSource)) {
dotnet nuget remove source "`"Steamware Nexus`""
dotnet nuget remove source "Steamware Nexus"
}
$hasSource = dotnet nuget list source | Select-String -Pattern "nexus-proxy-v3"
if (! [String]::IsNullOrWhiteSpace($hasSource)) {
dotnet nuget remove source nexus-proxy-v3
}
dotnet nuget add source https://nexus.steamware.net/repository/nuget-group-3/index.json -n "Steamware Nexus" -u nugetUser -p viaDante16 --store-password-in-clear-text
echo "Steamware Nexus Source added"
dotnet nuget add source https://nexus.steamware.net/repository/nuget-group-3/index.json -n "Steamware Nexus" -u nugetUser -p $NEXUS_PASSWD --store-password-in-clear-text
echo "Steamware Nexus Source added, final state:"
dotnet nuget list source
# helper creazione hash files x IIS
.hashBuild: &hashBuild
- |
$Target = $env:APP_NAME + "\bin\publish\" + $env:APP_NAME + ".zip"
$MD5 = Get-FileHash $Target -Algorithm MD5
$SHA1 = Get-FileHash $Target -Algorithm SHA1
New-Item $Target".md5"
New-Item $Target".sha1"
$MD5.Hash | Set-Content -Path $Target".md5"
$SHA1.Hash | Set-Content -Path $Target".sha1"
echo "Created HASH files for $Target"
# helper x send su NEXUS x pack
.nexusUpload: &nexusUpload
- |
Set-Alias mCurl C:\Windows\system32\curl.exe
$fileVers = $env:APP_NAME + "\Resources\VersNum.txt"
$VersNumb = Get-Content $fileVers
echo "Curr Version: $VersNumb"
if($CI_COMMIT_BRANCH -eq "master")
{
$version = "stable"
}
else
{
$version = "unstable"
}
$File2Send = Get-ChildItem($env:APP_NAME + "\bin\publish\*")
ForEach ($File in $File2Send) {
$FileName = Split-Path $File -leaf
mCurl -v -u GitLab:$NEXUS_PASSWD --upload-file $File https://nexus.steamware.net/repository/SWS/$env:NEXUS_PATH/$version/LAST/$FileName
mCurl -v -u GitLab:$NEXUS_PASSWD --upload-file $File https://nexus.steamware.net/repository/SWS/$env:NEXUS_PATH/$version/ARCHIVE/$VersNumb/$FileName
}
mCurl -v -u GitLab:$NEXUS_PASSWD --upload-file "$env:APP_NAME\Resources\manifest.xml" https://nexus.steamware.net/repository/SWS/$env:NEXUS_PATH/$version/LAST/manifest.xml
mCurl -v -u GitLab:$NEXUS_PASSWD --upload-file "$env:APP_NAME\Resources\ChangeLog.html" https://nexus.steamware.net/repository/SWS/$env:NEXUS_PATH/$version/LAST/ChangeLog.html
stages:
- build
@@ -31,95 +70,195 @@ stages:
CORE.Api:build:
stage: build
tags:
- win
before_script:
- *nuget-fix
- dotnet restore GPW.CORE.WRKLOG.sln
script:
- dotnet build GPW.CORE.Api/GPW.CORE.Api.csproj
stage: build
tags:
- win
variables:
APP_NAME: GPW.CORE.Api
SOL_NAME: GPW.CORE.WRKLOG
before_script:
- *nuget-fix
- dotnet restore "$env:SOL_NAME.sln"
script:
- dotnet build $env:APP_NAME/$env:APP_NAME.csproj
# ---------- BUILD ----------
CORE.WLOG:build:
stage: build
tags:
- win
variables:
APP_NAME: GPW.CORE.WRKLOG
SOL_NAME: GPW.CORE.WRKLOG
before_script:
- *nuget-fix
- dotnet restore GPW.CORE.WRKLOG.sln
- dotnet restore "$env:SOL_NAME.sln"
script:
- dotnet build GPW.CORE.WRKLOG/GPW.CORE.WRKLOG.csproj
- dotnet build $env:APP_NAME/$env:APP_NAME.csproj
CORE.Smart:build:
stage: build
tags:
- win
variables:
APP_NAME: GPW.CORE.Smart8
SOL_NAME: GPW.CORE.SMART8
before_script:
- *nuget-fix
- dotnet restore "$env:SOL_NAME.sln"
script:
- dotnet build $env:APP_NAME/$env:APP_NAME.csproj
# ---------- STAGING ----------
CORE.Api:staging:
stage: staging
tags:
- win
- win
variables:
APP_NAME: GPW.CORE.Api
SOL_NAME: GPW.CORE.WRKLOG
only:
- develop
needs: ["CORE.Api:build"]
before_script:
- *nuget-fix
- *nuget-fix
- dotnet restore "$env:SOL_NAME.sln"
script:
- dotnet publish -p:PublishProfile=IIS01.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=viadante16 -p:AllowUntrustedCertificate=true GPW.CORE.Api/GPW.CORE.Api.csproj
- dotnet build $env:APP_NAME/$env:APP_NAME.csproj
- dotnet publish -p:PublishProfile=IIS01.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=$IIS_PWD -p:AllowUntrustedCertificate=true -p:verbosity=quiet $env:APP_NAME/$env:APP_NAME.csproj
CORE.WLOG:staging:
stage: staging
tags:
- win
variables:
APP_NAME: GPW.CORE.WRKLOG
SOL_NAME: GPW.CORE.WRKLOG
only:
- develop
needs: ["CORE.WLOG:build"]
before_script:
- *nuget-fix
- *nuget-fix
- dotnet restore "$env:SOL_NAME.sln"
script:
- dotnet publish -p:PublishProfile=IIS01.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=viadante16 -p:AllowUntrustedCertificate=true GPW.CORE.WRKLOG/GPW.CORE.WRKLOG.csproj
- dotnet build $env:APP_NAME/$env:APP_NAME.csproj
- dotnet publish -p:PublishProfile=IIS01.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=$IIS_PWD -p:AllowUntrustedCertificate=true -p:verbosity=quiet $env:APP_NAME/$env:APP_NAME.csproj
CORE.Smart:staging:
stage: staging
tags:
- win
environment:
name: staging
url: https://iis01.egalware.com/GPW/CORE.Smart
variables:
APP_NAME: GPW.CORE.Smart8
SOL_NAME: GPW.CORE.SMART8
only:
- develop
needs: ["CORE.Smart:build"]
before_script:
- *nuget-fix
- dotnet restore "$env:SOL_NAME.sln"
script:
- dotnet build $env:APP_NAME/$env:APP_NAME.csproj
- dotnet publish -p:PublishProfile=IIS01.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=$IIS_PWD -p:AllowUntrustedCertificate=true -p:verbosity=quiet $env:APP_NAME/$env:APP_NAME.csproj
# ---------- DEPLOY ----------
CORE.Api:deploy:
stage: deploy
tags:
- win
only:
- main
needs: ["CORE.Api:build"]
script:
# IIS 02
- dotnet publish -p:PublishProfile=IIS02.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=viadante16 -p:AllowUntrustedCertificate=true GPW.CORE.Api/GPW.CORE.Api.csproj
# IIS DEV
- dotnet publish -p:PublishProfile=IIS03.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=viadante16 -p:AllowUntrustedCertificate=true GPW.CORE.Api/GPW.CORE.Api.csproj
stage: deploy
tags:
- win
environment:
name: production
url: https://seriate.egalware.com/GPW/CORE.Smart
variables:
APP_NAME: GPW.CORE.Api
SOL_NAME: GPW.CORE.WRKLOG
only:
- main
needs: ["CORE.Api:build"]
before_script:
- *nuget-fix
- dotnet restore "$env:SOL_NAME.sln"
script:
- dotnet build $env:APP_NAME/$env:APP_NAME.csproj
# IIS PROD
- dotnet publish -p:PublishProfile=IIS-PROD.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=$IIS_PWD -p:AllowUntrustedCertificate=true -p:verbosity=quiet $env:APP_NAME/$env:APP_NAME.csproj
CORE.WLOG:deploy:
stage: deploy
tags:
- win
only:
- main
needs: ["CORE.WLOG:build"]
script:
# IIS 02
- dotnet publish -p:PublishProfile=IIS02.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=viadante16 -p:AllowUntrustedCertificate=true GPW.CORE.WRKLOG/GPW.CORE.WRKLOG.csproj
# IIS DEV
- dotnet publish -p:PublishProfile=IIS03.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=viadante16 -p:AllowUntrustedCertificate=true GPW.CORE.WRKLOG/GPW.CORE.WRKLOG.csproj
stage: deploy
tags:
- win
variables:
APP_NAME: GPW.CORE.WRKLOG
SOL_NAME: GPW.CORE.WRKLOG
only:
- main
needs: ["CORE.WLOG:build"]
before_script:
- *nuget-fix
- dotnet restore "$env:SOL_NAME.sln"
script:
- dotnet build $env:APP_NAME/$env:APP_NAME.csproj
# IIS PROD
- dotnet publish -p:PublishProfile=IIS-PROD.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=$IIS_PWD -p:AllowUntrustedCertificate=true -p:verbosity=quiet $env:APP_NAME/$env:APP_NAME.csproj
CORE.Smart:deploy:
stage: deploy
tags:
- win
variables:
APP_NAME: GPW.CORE.Smart8
SOL_NAME: GPW.CORE.SMART8
only:
- main
needs: ["CORE.Smart:build"]
before_script:
- *nuget-fix
- dotnet restore "$env:SOL_NAME.sln"
script:
- dotnet build $env:APP_NAME/$env:APP_NAME.csproj
# IIS EXT
- dotnet publish -p:PublishProfile=IIS-EXT.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=$IIS_PWD -p:AllowUntrustedCertificate=true -p:verbosity=quiet $env:APP_NAME/$env:APP_NAME.csproj
# IIS INT
- dotnet publish -p:PublishProfile=IIS-INT.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=$IIS_PWD -p:AllowUntrustedCertificate=true -p:verbosity=quiet $env:APP_NAME/$env:APP_NAME.csproj
CORE.Api:release:
stage: release
tags:
- win
variables:
APP_NAME: GPW.CORE.Api
SOL_NAME: GPW.CORE.WRKLOG
only:
- main
except:
- branches
needs: ["CORE.Api:build"]
before_script:
- *nuget-fix
- dotnet restore "$env:SOL_NAME.sln"
artifacts:
paths:
- publish/
script:
- dotnet publish -c Release -o ./publish GPW.CORE.Api/GPW.CORE.Api.csproj
script:
- dotnet build $env:APP_NAME/$env:APP_NAME.csproj
- dotnet publish -p:PublishProfile=IISProfile.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release $env:APP_NAME/$env:APP_NAME.csproj -o:publish -p:verbosity=quiet
# qui il deploy su nexus...
- *hashBuild
- *nexusUpload
# script:
# - dotnet publish -c Release -o ./publish GPW.CORE.Api/GPW.CORE.Api.csproj
# ---------- RELEASE ----------
CORE.WLOG:release:
stage: release
tags:
- win
variables:
APP_NAME: GPW.CORE.WRKLOG
SOL_NAME: GPW.CORE.WRKLOG
only:
- main
except:
@@ -128,5 +267,36 @@ CORE.WLOG:release:
artifacts:
paths:
- publish/
script:
- dotnet publish -c Release -o ./publish GPW.CORE.WRKLOG/GPW.CORE.WRKLOG.csproj
script:
- dotnet build $env:APP_NAME/$env:APP_NAME.csproj
- dotnet publish -p:PublishProfile=IISProfile.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release $env:APP_NAME/$env:APP_NAME.csproj -o:publish -p:verbosity=quiet
# qui il deploy su nexus...
- *hashBuild
- *nexusUpload
# script:
# - dotnet publish -c Release -o ./publish GPW.CORE.WRKLOG/GPW.CORE.WRKLOG.csproj
CORE.Smart:release:
stage: release
tags:
- win
variables:
APP_NAME: GPW.CORE.Smart8
SOL_NAME: GPW.CORE.SMART8
only:
- main
except:
- branches
needs: ["CORE.Smart:build"]
artifacts:
paths:
- publish/
script:
- dotnet build $env:APP_NAME/$env:APP_NAME.csproj
- dotnet publish -p:PublishProfile=IISProfile.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release $env:APP_NAME/$env:APP_NAME.csproj -o:publish -p:verbosity=quiet
# qui il deploy su nexus...
- *hashBuild
- *nexusUpload
# script:
# - dotnet publish -c Release -o ./publish GPW.CORE.WRKLOG/GPW.CORE.WRKLOG.csproj
+35
View File
@@ -0,0 +1,35 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31912.275
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GPW.CORE.Data", "GPW.CORE.Data\GPW.CORE.Data.csproj", "{718B275D-7573-4CE2-87AF-57FCAAD71BD8}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{845EC4A6-7460-4897-8571-494E0EBB617E}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GPW.CORE.ADM", "GPW.CORE.ADM\GPW.CORE.ADM.csproj", "{4D06AE30-AD81-42FC-B66D-B072A794C599}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{718B275D-7573-4CE2-87AF-57FCAAD71BD8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{718B275D-7573-4CE2-87AF-57FCAAD71BD8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{718B275D-7573-4CE2-87AF-57FCAAD71BD8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{718B275D-7573-4CE2-87AF-57FCAAD71BD8}.Release|Any CPU.Build.0 = Release|Any CPU
{4D06AE30-AD81-42FC-B66D-B072A794C599}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4D06AE30-AD81-42FC-B66D-B072A794C599}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4D06AE30-AD81-42FC-B66D-B072A794C599}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4D06AE30-AD81-42FC-B66D-B072A794C599}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {AE057165-54C4-4678-8617-A03F0E8F6495}
EndGlobalSection
EndGlobal
+5
View File
@@ -0,0 +1,5 @@
{
"version": 1,
"isRoot": true,
"tools": {}
}
+63
View File
@@ -0,0 +1,63 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="GPW CORE ADMIN" />
<meta name="author" content="EgalWare" />
<link rel="shortcut icon" type="image/x-icon" href="images/favicon.ico" />
@* <base href="/" /> *@
<link rel="stylesheet" href="lib/bootstrap/css/bootstrap.min.css" />
<link rel="stylesheet" href="lib/font-awesome/css/all.min.css" />
<link rel="stylesheet" href="css/site.min.css" />
<link rel="stylesheet" href="css/fonts.min.css" />
<link rel="stylesheet" href="css/BlazorCal.min.css" />
<link rel="stylesheet" href="css/open-iconic/font/css/open-iconic-bootstrap.min.css" />
@* <link rel="stylesheet" href="bootstrap/bootstrap.min.css" />
<link rel="stylesheet" href="app.css" /> *@
<link rel="stylesheet" href="GPW.CORE.ADM.styles.css" />
@* <link rel="icon" type="image/png" href="favicon.png" /> *@
<link rel="manifest" href="manifest.json" />
@* <HeadOutlet /> *@
<HeadOutlet @rendermode="@(new InteractiveServerRenderMode(prerender: false))" />
<RadzenTheme Theme="material" @rendermode="@(new InteractiveServerRenderMode(prerender: false))" />
</head>
<body>
@* <Routes /> *@
@* <Routes @rendermode=RenderMode.InteractiveServer /> *@
<Routes @rendermode="@(new InteractiveServerRenderMode(prerender: false))" />
@* <script src="_framework/blazor.web.js"></script> *@
@* Gestione Blazor 6 x autoreconnect, da valutare *@
<script src="_framework/blazor.server.js" autostart="false"></script>
<script>
Blazor.start({
reconnectionOptions: {
maxRetries: 3600,
retryIntervalMilliseconds: 2000
},
}).then(() => {
Blazor.defaultReconnectionHandler._reconnectCallback = function (d) {
console.log("Client reconnected, waiting 3 sec and reload!");
setTimeout(function () {
document.location.reload();
}, 3000);
}
});
</script>
<script type="text/javascript" src="lib/bootstrap/js/bootstrap.min.js"></script>
@* <script type="text/javascript" src="lib/font-awesome/js/all.min.js"></script> *@
<script src="_content/Radzen.Blazor/Radzen.Blazor.js?v=@(typeof(Radzen.Colors).Assembly.GetName().Version)"></script>
<script src="lib/Chart.js/chart.js"></script>
<script src="lib/luxon/luxon.js"></script>
<script src="lib/chartjs-adapter-luxon/chartjs-adapter-luxon.js"></script>
<script src="lib/chartBoot.js"></script>
</body>
</html>
@@ -0,0 +1,91 @@
<div class="card shadow">
<div class="card-header">
<div class="d-flex justify-content-between">
<div class="px-0">
<h3>Approvazione Timbrature</h3>
</div>
<div class="px-0">
<select @bind="@IdxDipSel" class="form-select form-select-sm" @bind:after=ReloadData>
<option value="0">--- Selezionare ---</option>
@foreach (var item in ListDipendenti)
{
<option value="@item.IdxDipendente">@($"{item.Cognome} {item.Nome}")</option>
}
</select>
</div>
</div>
</div>
<div class="card-body p-1 small">
@if (ListRecords == null || isLoading)
{
<EgwCoreLib.Razor.LoadingData></EgwCoreLib.Razor.LoadingData>
}
else if (totalCount == 0)
{
<div class="alert alert-info">Nessun record trovato</div>
}
else
{
<table class="table table-striped table-sm text-start">
<thead>
<tr class="">
<th>
<button class="mx-1 btn btn-info btn-sm" @onclick="SelectAll"><i class="fa-solid fa-circle"></i></button>
<button class="btn btn-secondary opacity-50 btn-sm" @onclick="() => ForceReload(true)"><i class="fa-solid fa-circle"></i></button>
@if(ListUidSel.Count>0)
{
<button class="mx-1 btn btn-success btn-sm" @onclick="() => DoApproveSel()"><i class="fa-solid fa-thumbs-up"></i> ALL</button>
}
</th>
<th>Dipendente <Sorter ParamName="Dipendente" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
<th>DataOra <Sorter ParamName="DataOra" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
<th class="text-center">IN</th>
<th class="text-center"></th>
<th class="text-center">OUT</th>
<th class="text-end"></th>
</tr>
</thead>
<tbody>
@foreach (var item in ListRecords)
{
<tr class="align-middle">
<td>
<button class="mx-1 btn @CssCheckSel(item.UID) btn-sm" @onclick="() => ToggleUid(item.UID)"><i class="fa-solid @IconCheckSel(item.UID)"></i></button>
<button class="btn btn-success btn-sm" @onclick="() => DoApprove(item)"><i class="fa-solid fa-thumbs-up"></i></button>
</td>
<td>
@item.DipNav.Abbrev
</td>
<td>
@item.DataOra
</td>
<td class="text-center">
@if (item.Entrata ?? false)
{
<i class="fa-solid fa-xmark"></i>
}
</td>
<td class="text-center">
<button class="btn btn-warning btn-sm" @onclick="() => DoExchange(item)"><i class="fa-solid fa-arrow-right-arrow-left"></i></button>
</td>
<td class="text-center">
@if (!item.Entrata ?? false)
{
<i class="fa-solid fa-xmark"></i>
}
</td>
<td class="text-end">
<button class="btn btn-danger btn-sm" @onclick="() => DoDelete(item)"><i class="fa-solid fa-trash"></i></button>
</td>
</tr>
}
</tbody>
</table>
}
</div>
<div class="card-footer">
<EgwCoreLib.Razor.DataPager PageSize="@numRecord" currPage="@currPage" numRecordChanged="SetNumRec" numPageChanged="SetPage" totalCount="@totalCount" showLoading="@isLoading"></EgwCoreLib.Razor.DataPager>
</div>
</div>
@@ -0,0 +1,312 @@
using EgwCoreLib.Razor;
using GPW.CORE.Data;
using GPW.CORE.Data.DbModels;
using GPW.CORE.Data.Services;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using NLog;
namespace GPW.CORE.ADM.Components.Compo
{
public partial class ApprovTimbMan : IDisposable
{
#region Public Methods
public void Dispose()
{
AppMServ.EA_SearchUpdated -= AppMServ_EA_SearchUpdated;
}
#endregion Public Methods
#region Protected Properties
[Inject]
protected MessageService AppMServ { get; set; } = null!;
[Inject]
protected GpwDataService GDataServ { get; set; } = null!;
protected int IdxDipSel { get; set; } = 0;
[Inject]
protected IJSRuntime JSRuntime { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected string CssCheckSel(string uid)
{
return ListUidSel.Contains(uid) ? "btn-info" : "btn-secondary opacity-50";
}
protected async Task DoApprove(TimbratureModel selItem)
{
isLoading = true;
#if false
#endif
// se non si tratta di una timbratura "last second"...
if (selItem.DataOra.Hour != 23 && selItem.DataOra.Minute != 59 && selItem.DataOra.Second != 59)
{
// arrotondo ingresso/uscita ai 5 minuti secondo sia entrata o uscita...
var dtTimb = Utils.DateRounded(selItem.DataOra, 5, !(selItem.Entrata ?? false));
selItem.DataOra = dtTimb;
}
// indico approvato
selItem.Approv = true;
// salvo!
bool fatto = await GDataServ.TimbratureUpdate(selItem);
//bool fatto = await GDataServ.TimbratureUpdateRound(selItem);
if (fatto)
{
await ReloadData();
}
await InvokeAsync(StateHasChanged);
}
protected async Task DoApproveSel()
{
if (!await JSRuntime.InvokeAsync<bool>("confirm", $"Sicuro di voler approvare i {ListUidSel.Count} record selezionati?"))
return;
isLoading = true;
await InvokeAsync(StateHasChanged);
int numProc = 0;
foreach (var item in ListRecords)
{
// se selezionato...
if (ListUidSel.Contains(item.UID))
{
// se non si tratta di una timbratura "last second"...
if (item.DataOra.Hour != 23 && item.DataOra.Minute != 59 && item.DataOra.Second != 59)
{
// arrotondo ingresso/uscita ai 5 minuti secondo sia entrata o uscita...
var dtTimb = Utils.DateRounded(item.DataOra, 5, !(item.Entrata ?? false));
item.DataOra = dtTimb;
}
// indico approvato
item.Approv = true;
// salvo!
bool fatto = await GDataServ.TimbratureUpdate(item);
if (fatto)
{
numProc++;
}
}
}
await Task.Delay(1);
if (numProc > 0)
{
await ReloadData();
}
await Task.Delay(1);
await InvokeAsync(StateHasChanged);
}
protected async void DoDelete(TimbratureModel selItem)
{
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Sicuro di voler eliminare il record?"))
return;
isLoading = true;
bool fatto = await GDataServ.TimbratureDelete(selItem);
if (fatto)
{
await ReloadData();
}
await InvokeAsync(StateHasChanged);
}
protected async void DoExchange(TimbratureModel selItem)
{
isLoading = true;
selItem.Entrata = !selItem.Entrata;
bool fatto = await GDataServ.TimbratureUpdate(selItem);
if (fatto)
{
await ReloadData();
}
await InvokeAsync(StateHasChanged);
}
protected async Task ForceReload(bool force)
{
ListUidSel = new List<string>();
await ReloadData();
}
protected string IconCheckSel(string uid)
{
return ListUidSel.Contains(uid) ? "fa-circle" : "fa-circle";
}
protected override async Task OnInitializedAsync()
{
CurrSearch = "";
AppMServ.SearchVal = "";
AppMServ.EA_SearchUpdated += AppMServ_EA_SearchUpdated;
numRecord = await AppMServ.NumRowGridGet(gridKey);
var rawList = await GDataServ.DipendentiGetAll();
ListDipendenti = rawList.Where(x => (x.Attivo ?? false)).ToList();
}
protected override async Task OnParametersSetAsync()
{
await ReloadData();
}
protected void SelectAll()
{
if (ListRecords != null)
{
ListUidSel = ListRecords.Select(x => x.UID).ToList();
}
}
protected async Task SetNumRec(int newNum)
{
numRecord = newNum;
currPage = 1;
await AppMServ.NumRowGridSet(gridKey, newNum);
await InvokeAsync(ReloadData);
}
protected async Task SetPage(int newNum)
{
currPage = newNum;
await InvokeAsync(ReloadData);
}
protected async Task SortRequested(Sorter.SortCallBack e)
{
sortField = e.ParamName;
sortAsc = e.IsAscending;
await ReloadData();
}
protected async void ToggleUid(string uid)
{
if (ListUidSel.Contains(uid))
{
ListUidSel.Remove(uid);
}
else
{
ListUidSel.Add(uid);
}
await ReloadData();
await InvokeAsync(StateHasChanged);
}
#endregion Protected Methods
#region Private Fields
private static Logger Log = LogManager.GetCurrentClassLogger();
private string gridKey = "ApprovTimbMan";
private bool sortAsc = true;
private string sortField = "";
#endregion Private Fields
#region Private Properties
private int currPage { get; set; } = 1;
private string CurrSearch { get; set; } = "";
private bool filtDip { get; set; } = false;
private bool isLoading { get; set; } = false;
private List<DipendentiModel> ListDipendenti { get; set; } = new List<DipendentiModel>();
private List<TimbratureModel>? ListRecords { get; set; } = null;
private List<string> ListUidSel { get; set; } = new List<string>();
private int numRecord { get; set; } = 10;
private List<TimbratureModel>? SearchRecords { get; set; } = null;
private int totalCount { get; set; } = 0;
#endregion Private Properties
#region Private Methods
private async void AppMServ_EA_SearchUpdated()
{
CurrSearch = AppMServ.SearchVal;
await ReloadData();
await InvokeAsync(StateHasChanged);
}
private async Task ReloadData()
{
currPage = 1;
isLoading = true;
ListRecords = null;
try
{
SearchRecords = await GDataServ.TimbratureRichieste();
// verifico filtro per IdxDip
if (IdxDipSel > 0)
{
SearchRecords = SearchRecords.Where(x => x.IdxDipendente == IdxDipSel).ToList();
}
}
catch (Exception ex)
{
Log.Error($"Eccezione in recupero dati{Environment.NewLine}{ex}");
}
totalCount = SearchRecords.Count;
SortTable();
isLoading = false;
}
private void SortTable()
{
if (SearchRecords != null)
{
// se ho ordinamento riordino...
if (!string.IsNullOrEmpty(sortField))
{
switch (sortField)
{
case "Dipendente":
if (sortAsc)
{
SearchRecords = SearchRecords.OrderBy(x => x.DipNav.Abbrev).ToList();
}
else
{
SearchRecords = SearchRecords.OrderByDescending(x => x.DipNav.Abbrev).ToList();
}
break;
case "DataOra":
if (sortAsc)
{
SearchRecords = SearchRecords.OrderBy(x => x.DataOra).ToList();
}
else
{
SearchRecords = SearchRecords.OrderByDescending(x => x.DataOra).ToList();
}
break;
default:
break;
}
}
// filtro x display
ListRecords = SearchRecords
.Skip(numRecord * (currPage - 1))
.Take(numRecord)
.ToList();
}
else
{
ListRecords = new List<TimbratureModel>();
}
}
#endregion Private Methods
}
}
@@ -0,0 +1,144 @@
@if (isLoading)
{
<LoadingData></LoadingData>
}
else
{ @if (isSendingData)
{
<ProgressDisplay Title="Salvataggio ed invio richiesta" CurrVal="@sendDataVal" NextVal="@sendDataNextVal" MaxVal="@sendDataMaxVal" ExpTimeMSec="1000"></ProgressDisplay>
}
@if (ListRecords == null)
{
<LoadingData DisplaySize="LoadingData.CtrlSize.Small"></LoadingData>
}
else
{
@if (showAdd)
{
<ul class="list-group">
<li class="list-group-item">
<div class="d-flex justify-content-between">
<div class="px-0">
<b>Data</b>
</div>
<div class="px-2">
<input type="date" class="form-control text-end" @bind="@currRecord.data">
</div>
</div>
</li>
<li class="list-group-item">
<div class="d-flex justify-content-between">
<div class="px-0">
<b>Giust</b>
</div>
<div class="px-2">
<div class="input-group input-group-sm">
<select @bind="@currRecord.codGiust" class="form-select">
<option value="">--- Selezionare Causale ---</option>
@if (ListGiust != null)
{
@foreach (var giust in ListGiust)
{
<option value="@giust.codGiust">@giust.descrizione</option>
}
}
</select>
</div>
</div>
</div>
</li>
<li class="list-group-item">
<div class="d-flex justify-content-between">
<div class="px-0">
<b>Descrizione</b>
</div>
<div class="px-2">
<input class="form-control form-control-sm small" @bind="@currRecord.descrizione"></input>
</div>
</div>
</li>
@* <li class="list-group-item">
<div class="d-flex justify-content-between">
<div class="px-0">
<b>Stato</b>
<span class="small">(confermato)</span>
</div>
<div class="px-0">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" @bind="@currRecord.Conf">
</div>
</div>
</div>
</li> *@
<li class="list-group-item">
<div class="row">
<div class="col">
<button class="btn btn-warning w-100" @onclick="ToggleEdit"><i class="fas fa-window-close"></i> Cancel</button>
</div>
<div class="col">
@if (!string.IsNullOrEmpty(currRecord.codGiust))
{
<button class="btn btn-success w-100" @onclick="() => DoSave()"><i class="far fa-save"></i> Update</button>
}
else
{
<button class="btn btn-secondary w-100" disabled><i class="far fa-save"></i> Update</button>
}
</div>
</div>
</li>
</ul>
}
@if (ListRecords.Count == 0)
{
<div class="alert alert-warning">
<h4>Nessu record registrato!</h4>
<button class="btn btn-success btn-sm" @onclick="() => ToggleEdit()"><i class="fas fa-plus"></i> Inserisci Malattia</button>
</div>
}
else
{
<table class="table table-sm table-striped table-responsive-md border border-dark">
<thead>
<tr class="bg-dark text-light">
<th>
<button class="btn btn-success btn-sm" @onclick="() => AddNew()"><i class="fas fa-plus"></i></button>
</th>
<th>Data</th>
<th class="text-center">Tipo</th>
<th class="text-end">Descrizione</th>
<th class="text-end"></th>
</tr>
</thead>
<tbody>
@foreach (var item in ListRecords)
{
<tr>
<td>
<button class="btn btn-primary btn-sm" @onclick="() => DoEdit(item)"><i class="fas fa-pen"></i></button>
</td>
<td class="text-nowrap">
@($"{item.data:yyyy-MM-dd dddd}")
</td>
<td>
@item.codGiust
</td>
<td class="text-center">
@item.descrizione
</td>
<td class="text-end">
<button class="btn btn-danger btn-sm" @onclick="() => DoDelete(item)"><i class="fas fa-trash-alt"></i></button>
</td>
</tr>
}
</tbody>
</table>
<div>
<EgwCoreLib.Razor.DataPager PageSize="@numRecord" currPage="@currPage" numRecordChanged="SetNumRec" numPageChanged="SetPage" totalCount="@totalCount" showLoading="@isLoading" NumPages="10" PageSizeList="@PageSizeListSpec"></EgwCoreLib.Razor.DataPager>
</div>
}
}
}
@@ -0,0 +1,235 @@
using GPW.CORE.Data.DbModels;
using GPW.CORE.Data.Services;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using NLog;
namespace GPW.CORE.ADM.Components.Compo
{
public partial class CalAzMan
{
#region Public Properties
[Parameter]
public DateTime DtEnd { get; set; } = new DateTime(DateTime.Today.Year + 1, 1, 1);
[Parameter]
public DateTime DtStart { get; set; } = new DateTime(DateTime.Today.Year, 1, 1);
[Parameter]
public bool isLoading { get; set; }
[Parameter]
public EventCallback<bool> ReportUpdate { get; set; }
#endregion Public Properties
#region Protected Fields
protected List<int> PageSizeListSpec = new List<int>() { 5, 10, 15, 20 };
#endregion Protected Fields
#region Protected Properties
[Inject]
protected MessageService AppMServ { get; set; } = null!;
[Inject]
protected GpwDataService GDataServ { get; set; } = null!;
[Inject]
protected IJSRuntime JSRuntime { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected override async Task OnInitializedAsync()
{
ListGiust = await GDataServ.AnagGiust();
// recupero preferenze utente...
await InitUserPref();
}
protected override async Task OnParametersSetAsync()
{
currPage = 1;
await ReloadData();
}
protected async Task SetNumRec(int newNum)
{
numRecord = newNum;
currPage = 1;
await AppMServ.NumRowGridSet(gridKey, newNum);
await InvokeAsync(ReloadData);
}
protected async Task SetPage(int newNum)
{
currPage = newNum;
await InvokeAsync(ReloadData);
}
#endregion Protected Methods
#region Private Fields
private static Logger Log = LogManager.GetCurrentClassLogger();
private string gridKey = "CalChiusura";
private bool isSendingData = false;
private List<CalFesteFerieModel>? ListRecords = null;
private List<CalFesteFerieModel>? SearchRecords = null;
private int sendDataMaxVal = 100;
private int sendDataNextVal = 0;
private int sendDataVal = 0;
private bool showAdd = false;
#endregion Private Fields
#region Private Properties
private int currPage { get; set; } = 1;
private CalFesteFerieModel currRecord { get; set; } = new CalFesteFerieModel();
private string NomeDip
{
get
{
string answ = "per cortesia";
if (AppMServ != null && AppMServ.RigaDip != null)
{
answ = $"{AppMServ.RigaDip.Nome}";
}
return answ;
}
}
private int numRecord { get; set; } = 10;
private int totalCount { get; set; } = 0;
#endregion Private Properties
#region Private Methods
private void DoEdit(CalFesteFerieModel selItem)
{
currRecord = selItem;
showAdd = true;
}
/// <summary>
/// Registra il record
/// </summary>
/// <returns></returns>
private async Task DoSave()
{
// chiedo verifica
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Confermi modifica record?"))
return;
isSendingData = true;
sendDataVal = 0;
sendDataNextVal = 5;
await Task.Delay(1);
await Task.Delay(1);
// effettuo insert...
sendDataVal = 5;
sendDataNextVal = 90;
await Task.Delay(1);
await GDataServ.CalFestFerieUpsert(currRecord);
// effettuo insert...
sendDataVal = 100;
sendDataNextVal = 100;
// aggiorno display...
await Task.Delay(1);
showAdd = false;
await ReloadData();
await ReportUpdate.InvokeAsync(true);
isSendingData = false;
}
/// <summary>
/// Init preferenze utente
/// </summary>
/// <returns></returns>
private async Task InitUserPref()
{
try
{
numRecord = await AppMServ.NumRowGridGet(gridKey);
}
catch (Exception exc)
{
Log.Error($"Eccezione in InitUserPref{Environment.NewLine}{exc}");
}
}
private async Task ReloadData()
{
SearchRecords = null;
await Task.Delay(1);
SearchRecords = await GDataServ.CalFestFeriePeriodo(DtStart, DtEnd);
// conteggio!
totalCount = SearchRecords.Count;
// paginazione
ListRecords = SearchRecords
.OrderByDescending(x => x.data)
.Skip(numRecord * (currPage - 1))
.Take(numRecord)
.ToList();
await Task.Delay(1);
await InvokeAsync(StateHasChanged);
}
private void ToggleEdit()
{
showAdd = !showAdd;
}
private void AddNew()
{
showAdd = true;
currRecord = new CalFesteFerieModel()
{
data = DateTime.Today,
codGiust = "FER",
descrizione = "CHIUSURA UFFICIO"
};
}
private List<AnagGiustModel>? ListGiust = null;
private async Task DoDelete(CalFesteFerieModel selItem)
{
// chiedo verifica
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Sicuro di voler eliminare il record selezionato??"))
return;
await Task.Delay(1);
isSendingData = true;
sendDataVal = 0;
sendDataNextVal = 90;
await Task.Delay(1);
await InvokeAsync(StateHasChanged);
await GDataServ.CalFestFerieDelete(selItem);
sendDataVal = 100;
sendDataNextVal = 100;
await Task.Delay(1);
await ReloadData();
await ReportUpdate.InvokeAsync(true);
isSendingData = false;
}
#endregion Private Methods
}
}
@@ -0,0 +1,63 @@
<div class="card bg-dark text-light">
<div class="card-header ">
<div class="row">
<div class="col-4 text-start">
<div class="btn-group" role="group">
<button type="button" class="btn btn-sm @btnSel("PER")" @onclick="ToggPer">Permessi</button>
<button type="button" class="btn btn-sm @btnSel("FER")" @onclick="ToggFer">Ferie</button>
<button type="button" class="btn btn-sm @btnSel("MAL")" @onclick="ToggMal">Malattie</button>
<button type="button" class="btn btn-sm @btnSel("FEST")" @onclick="ToggFest">Feste</button>
<button type="button" class="btn btn-sm @btnSel("CHIU")" @onclick="ToggChiu">Chiusure</button>
</div>
</div>
<div class="col-4 text-center text-uppercase h5">
<b>Calendario Aziendale</b>
</div>
<div class="col-4 text-end">
<div class="d-flex justify-content-around">
@if (currView == "year" || currView == "planner")
{
<div class="small">
<RadzenStack Orientation="Orientation.Horizontal" AlignItems="AlignItems.Center" Gap="0.5rem" class="rz-px-2">
<RadzenLabel Text="Mese:" />
<RadzenDropDown @bind-Value="@startMonth" Change="StartMonthChange" TextProperty="Text" ValueProperty="Value" Data="@(Enum.GetValues(typeof(Month)).Cast<Month>().Where(x => ((int)x % 3 == 0)).Select(t => new { Text = $"{t}", Value = t }))" class="rz-display-inline-flex small" />
</RadzenStack>
</div>
}
</div>
</div>
</div>
</div>
<div class="card-body bg-body text-dark p-1">
<div style="@schedHeight">
<RadzenScheduler @ref=@scheduler style="height: 100%;" Culture=@(new System.Globalization.CultureInfo("it-IT"))
TItem="EventDTO" Data="@EvDtoFilt" SelectedIndex="@selectedIndex" Date="@SelDate"
StartProperty="DtStart" EndProperty="DtEnd" TextProperty="CodTipo"
SlotRender=@OnSlotRender SlotSelect=@OnSlotSelect
AppointmentSelect=@OnAppointmentSelect AppointmentRender=@OnAppointmentRender
LoadData=OnLoadData>
<Template Context="EvDTO">
<div>
<strong>@EvDTO.CodTipo</strong> | @EvDTO.Abbrev
</div>
<small>
@if (EvDTO.CodTipo == "PERM" || EvDTO.CodTipo == "104")
{
@($"{EventDTO.DateForm(EvDTO.CodTipo, EvDTO.DtStart)} --> {EventDTO.DateForm(EvDTO.CodTipo, EvDTO.DtEnd)}")
}
</small>
</Template>
<ChildContent>
<RadzenDayView />
<RadzenWeekView />
<RadzenMonthView MaxAppointmentsInSlot="4" />
<RadzenYearPlannerView StartMonth="@startMonth" MaxAppointmentsInSlot="3" />
@* <RadzenYearTimelineView StartMonth="@startMonth" /> *@
<RadzenYearView StartMonth="@startMonth" />
</ChildContent>
</RadzenScheduler>
</div>
</div>
</div>
@@ -0,0 +1,341 @@
using Microsoft.AspNetCore.Components;
using Microsoft.Identity.Client;
using Radzen.Blazor.Rendering;
using Radzen.Blazor;
using static EgwCoreLib.Razor.Toggler;
using Radzen;
using System;
using static System.Runtime.InteropServices.JavaScript.JSType;
using GPW.CORE.Data.DTO;
using System.Diagnostics;
namespace GPW.CORE.ADM.Components.Compo
{
public partial class CalendarioAziendale
{
#region Public Properties
[Parameter]
public EventCallback<DateTime> DtReq { get; set; }
[Parameter]
public List<EventDTO> EvDtoList { get; set; } = null!;
[Parameter]
public DateTime firstDate { get; set; } = new DateTime(DateTime.Today.Year, 1, 1);
[Parameter]
public bool ShowNeedConf { get; set; } = false;
[Parameter]
public DateTime maxDate { get; set; } = new DateTime(DateTime.Today.Year + 1, 1, 1);
[Parameter]
public DateTime minDate { get; set; } = new DateTime(DateTime.Today.Year, 1, 1);
[Parameter]
public int MonthDispl
{
get => cMonth;
set => cMonth = value;
}
[Parameter]
public EventCallback<int> MonthReq { get; set; }
#endregion Public Properties
#region Protected Fields
protected RadzenScheduler<EventDTO> scheduler = null!;
#endregion Protected Fields
#region Protected Enums
protected enum Viste
{
Day,
Week,
Month,
Planner,
Year
}
#endregion Protected Enums
#region Protected Properties
protected int currMonth
{
get => cMonth;
set
{
if (cMonth != value)
{
cMonth = value;
MonthReq.InvokeAsync(value);
}
}
}
[Inject]
protected DialogService DialogService { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected async Task addMonth(int numMesi)
{
firstDate = firstDate.AddMonths(numMesi);
// verifico limiti...
if (numMesi > 0)
{
firstDate = firstDate > maxDate ? maxDate : firstDate;
}
else
{
firstDate = firstDate < minDate ? minDate : firstDate;
}
await Task.Delay(1);
}
protected override async Task OnInitializedAsync()
{
await Task.Delay(1);
// il mese viene preimpostato sul trimestre corrente...
startMonth = (Month)((DateTime.Today.Month / 6) * 6);
}
protected override void OnParametersSet()
{
FilterData();
scheduler.Reload();
}
protected async Task StartMonthChange()
{
await scheduler.Reload();
}
#endregion Protected Methods
#region Private Fields
private int selectedIndex = 2;
#endregion Private Fields
#region Private Properties
private int cMonth { get; set; } = 3;
private string currView { get; set; } = "";
private List<EventDTO> EvDtoFilt { get; set; } = new List<EventDTO>();
private string schedHeight { get; set; } = "height: 50rem;";
private DateTime SelDate { get; set; } = DateTime.Today;
private Month startMonth { get; set; } = Month.January;
#endregion Private Properties
#region Private Methods
private void FilterData()
{
// in primis copio tutto
EvDtoFilt = EvDtoList;
if (ShowNeedConf)
{
EvDtoFilt = EvDtoFilt.Where(x => !x.Conf).ToList();
}
// controllo ogni toggle...
if (!showChiu)
{
EvDtoFilt = EvDtoFilt
.Where(x => !x.IsCompany || (x.IsCompany && !x.CodTipo.Equals("FER", StringComparison.InvariantCultureIgnoreCase)))
.ToList();
}
if (!showFer)
{
EvDtoFilt = EvDtoFilt
.Where(x => !x.CodTipo.Equals("FER", StringComparison.InvariantCultureIgnoreCase) || (x.CodTipo.Equals("FER", StringComparison.InvariantCultureIgnoreCase) && x.IsCompany))
.ToList();
}
if (!showFest)
{
EvDtoFilt = EvDtoFilt
.Where(x => !x.CodTipo.Equals("FEST", StringComparison.InvariantCultureIgnoreCase))
.ToList();
}
if (!showMal)
{
EvDtoFilt = EvDtoFilt
.Where(x => !x.CodTipo.Equals("MAL", StringComparison.InvariantCultureIgnoreCase))
.ToList();
}
if (!showPer)
{
EvDtoFilt = EvDtoFilt
.Where(x => !x.CodTipo.Equals("PERM", StringComparison.InvariantCultureIgnoreCase) && !x.CodTipo.Equals("104", StringComparison.InvariantCultureIgnoreCase))
.ToList();
}
}
private bool showChiu { get; set; } = true;
private bool showFer { get; set; } = true;
private bool showFest { get; set; } = true;
private bool showMal { get; set; } = true;
private bool showPer { get; set; } = true;
protected string btnSel(string bName)
{
bool answ = false;
switch (bName)
{
case "CHIU":
answ = showChiu;
break;
case "FER":
answ = showFer;
break;
case "FEST":
answ = showFest;
break;
case "MAL":
answ = showMal;
break;
case "PER":
answ = showPer;
break;
default:
break;
}
return answ ? "btn-primary" : "btn-secondary";
}
protected void ToggMal()
{
showMal = !showMal;
FilterData();
}
protected void ToggPer()
{
showPer = !showPer;
FilterData();
}
protected void ToggFer()
{
showFer = !showFer;
FilterData();
}
protected void ToggFest()
{
showFest = !showFest;
FilterData();
}
protected void ToggChiu()
{
showChiu = !showChiu;
FilterData();
}
private void OnAppointmentRender(SchedulerAppointmentRenderEventArgs<EventDTO> args)
{
// Never call StateHasChanged in AppointmentRender - would lead to infinite loop
args.Attributes["style"] = $"background: {args.Data.Color}; color: {args.Data.ForeColor};";
}
private async Task OnAppointmentSelect(SchedulerAppointmentSelectEventArgs<EventDTO> selEv)
{
var copy = selEv.Data.Clone();
await Task.Delay(1);
var data = await DialogService.OpenAsync<TaskDetail>("", new Dictionary<string, object> { { "ThisTask", copy } });
}
private async Task OnLoadData(SchedulerLoadDataEventArgs args)
{
await Task.Delay(1);
currView = scheduler.SelectedView.Text.ToLowerInvariant();
// controllo se sia cambiata data... di almeno 1 anno in questo caso...
if (SelDate != scheduler.Date || Math.Abs(scheduler.Date.Subtract(args.Start).TotalDays) > 365)
{
SelDate = args.Start.AddMonths(1);
// riporto data al controller parent...
await DtReq.InvokeAsync(SelDate);
}
//schedHeight = (currView == "year" || currView == "planner") ? "height: 60rem;" : "height: 50rem;";
// // Get the appointments for between the Start and End
// data = await MyAppointmentService.GetData(selEv.Start, selEv.End);
}
private void OnSlotRender(SchedulerSlotRenderEventArgs args)
{
// Highlight today in month view
if (args.View.Text == "Month" && args.Start.Date == DateTime.Today)
{
args.Attributes["style"] = "background: var(--rz-scheduler-highlight-background-color, rgba(255,220,40,.2));";
}
// Highlight working hours (9-18)
if ((args.View.Text == "Week" || args.View.Text == "Day") && args.Start.Hour > 8 && args.Start.Hour < 19)
{
args.Attributes["style"] = "background: var(--rz-scheduler-highlight-background-color, rgba(255,220,40,.2));";
}
}
private async Task OnSlotSelect(SchedulerSlotSelectEventArgs args)
{
int prevIdx = selectedIndex;
await Task.Delay(1);
// verifico indice corretto della vista...
switch (args.View.Text)
{
case "Day":
selectedIndex = 0;
break;
case "Week":
selectedIndex = 1;
break;
case "Month":
selectedIndex = 2;
break;
case "Planner":
selectedIndex = 3;
break;
case "Year":
selectedIndex = 4;
break;
default:
break;
}
if (prevIdx != selectedIndex)
{
await scheduler.Reload();
}
await Task.Delay(1);
if (selectedIndex > 0)
{
selectedIndex--;
}
// imposto al data selezionata
SelDate = args.Start;
// riporto data al controller parent...
await DtReq.InvokeAsync(SelDate);
}
#endregion Private Methods
}
}
@@ -0,0 +1,78 @@
<div class="row g-1">
<div class="col-md-3">
<div class="form-floating">
<input type="text" class="form-control" @bind="@CurrRecord.RagSociale">
<label class="small">Rag.Sociale</label>
</div>
</div>
<div class="col-md-3">
<div class="form-floating">
<input type="text" class="form-control" @bind="@CurrRecord.Indirizzo">
<label class="small">Indirizzo</label>
</div>
</div>
<div class="col-md-3">
<div class="form-floating">
<input type="text" class="form-control" @bind="@CurrRecord.Citta">
<label class="small">Citta</label>
</div>
</div>
<div class="col-md-1">
<div class="form-floating">
<input type="number" class="form-control" @bind="@CurrRecord.Cap">
<label class="small">CAP</label>
</div>
</div>
<div class="col-md-1">
<div class="form-floating">
<input type="text" class="form-control" @bind="@CurrRecord.Prov">
<label class="small">Prov</label>
</div>
</div>
<div class="col-md-1">
<div class="form-floating">
<span class="form-control">
<span class="form-check form-switch">
<input type="checkbox" class="form-check-input" @bind="@CurrRecord.Attivo">
</span>
</span>
<label class="small">Att.</label>
</div>
</div>
<div class="col-md-3">
<div class="form-floating">
<input type="text" class="form-control" @bind="@CurrRecord.Cf">
<label class="small">Cod.Fisc</label>
</div>
</div>
<div class="col-md-3">
<div class="form-floating">
<input type="text" class="form-control" @bind="@CurrRecord.PIva">
<label class="small">P.Iva</label>
</div>
</div>
<div class="col-md-3">
<div class="form-floating">
<input type="text" class="form-control" @bind="@CurrRecord.Email">
<label class="small">Email</label>
</div>
</div>
<div class="col-md-3">
<div class="form-floating">
<input type="text" class="form-control" @bind="@CurrRecord.Tel">
<label class="small">Telefono</label>
</div>
</div>
</div>
<div class="row g-1">
<div class="col-md-9">
<div class="form-floating">
<textarea class="form-control" @bind="@CurrRecord.Nota" rows="2" style="height: 5.5rem;"></textarea>
<label class="small">Note</label>
</div>
</div>
<div class="col-md-3 pt-2">
<button class="btn btn-success w-100" @onclick="() => DoSave()"><i class="fas fa-floppy-disk"></i> Save</button>
<button class="btn btn-warning w-100" @onclick="() => DoCancel()"><i class="fas fa-ban"></i> Cancel</button>
</div>
</div>
@@ -0,0 +1,46 @@
using GPW.CORE.Data.DbModels;
using GPW.CORE.Data.Services;
using Microsoft.AspNetCore.Components;
namespace GPW.CORE.ADM.Components.Compo
{
public partial class ClientiEdit
{
#region Public Properties
[Parameter]
public AnagClientiModel? CurrRecord { get; set; } = null;
[Parameter]
public EventCallback<bool> EC_update { get; set; }
#endregion Public Properties
#region Protected Properties
[Inject]
protected GpwDataService GDataServ { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected async Task DoSave()
{
bool fatto = false;
await Task.Delay(1);
if (CurrRecord != null)
{
fatto = await GDataServ.AnagClientiUpsert(CurrRecord);
}
await EC_update.InvokeAsync(fatto);
}
protected async Task DoCancel()
{
await EC_update.InvokeAsync(true);
}
#endregion Protected Methods
}
}
@@ -0,0 +1,160 @@
@if (SelItem != null)
{
<div class="modal fade show" tabindex="-1" style="display:block; background-color: rgba(10,10,10,.6);" aria-modal="true" role="dialog" data-keyboard="true">
<div class="modal-dialog modal-xl">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Edit Cliente <b>@SelItem.IdxCliente</b></h4>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" @onclick="() => ForceReload(true)"></button>
</div>
<div class="modal-body p-1 small">
<ClientiEdit CurrRecord=@SelItem EC_update="ForceReload"></ClientiEdit>
</div>
</div>
</div>
</div>
}
<div class="card shadow">
<div class="card-header">
<div class="d-flex justify-content-between">
<div class="px-0">
<h3>@Traduci("ManClienti")</h3>
</div>
<div class="px-0">
<div class="d-flex">
<div class="px-1">
<div class="form-check form-switch">
<Toggler SelFilter="@ToggleData" FilterChanged="evToggled"></Toggler>
</div>
</div>
<div class="px-0">
<button class="btn btn-sm btn-success" @onclick=CreateNew><i class="fa-solid fa-plus"></i> Add New</button>
</div>
</div>
</div>
</div>
</div>
<div class="card-body p-1 small">
@if (ListRecords == null || isLoading)
{
<EgwCoreLib.Razor.LoadingData></EgwCoreLib.Razor.LoadingData>
}
else if (totalCount == 0)
{
<div class="alert alert-info">Nessun record trovato</div>
}
else
{
<table class="table table-striped table-sm text-start">
<thead>
<tr class="">
<th>
<button class="btn btn-primary btn-sm" @onclick="() => ForceReload(true)"><i class="fa-solid fa-rotate"></i></button>
</th>
<th>RagSoc <Sorter ParamName="RagSoc" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
<th>Indirizzo <Sorter ParamName="Indirizzo" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
<th>Contatti <Sorter ParamName="Contatti" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
<th>P.Iva - C.Fisc <Sorter ParamName="PICF" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
<th class="text-end"><Sorter ParamName="Note" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter> Note</th>
<th class="text-end"><Sorter ParamName="Attivo" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter> Attivo</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in ListRecords)
{
<tr class="align-middle @CheckSel(item)">
<td>
@if (SelItem == null)
{
@* <button class="btn btn-info btn-sm" @onclick="() => DoSelect(item)"><i class="fa-solid fa-search"></i></button> *@
<button class="btn btn-primary btn-sm" @onclick="() => DoEdit(item)"><i class="fa-solid fa-edit"></i></button>
}
else
{
@* <button class="btn btn-secondary btn-sm" disabled><i class="fa-solid fa-search"></i></button> *@
<button class="btn btn-secondary btn-sm" disabled><i class="fa-solid fa-edit"></i></button>
}
</td>
<td>
<div class="fw-bold fs-5">
@item.RagSociale
</div>
</td>
<td>
<div>
@item.Indirizzo
</div>
<div class="d-flex">
<div class="px-0">@item.Cap, @item.Citta - @item.Prov</div>
</div>
</td>
<td>
<div class="d-flex small">
<div class="px-1"><i class="fa-regular fa-envelope"></i></div>
<div class="px-0">@item.Email</div>
</div>
<div class="d-flex small">
<div class="px-1"><i class="fa-solid fa-phone"></i></div>
<div class="px-0">@item.Tel</div>
</div>
</td>
<td>
<div class="d-flex small">
<div class="px-1">P.Iva:</div>
<div class="px-0"><b>@item.PIva</b></div>
</div>
<div class="d-flex small">
<div class="px-1">CFis:</div>
<div class="px-0"><b>@item.Cf</b></div>
</div>
</td>
<td class="text-end small">
@item.Nota
</td>
<td class="text-end">
@if (item.Attivo)
{
<i class="fa-solid fa-certificate text-success"></i>
}
else
{
<i class="fa-solid fa-certificate text-secondary"></i>
}
</td>
<td>
@if (item.Attivo)
{
<button class="btn btn-danger btn-sm" @onclick="() => DoDelete(item)"><i class="fa-solid fa-trash"></i></button>
}
else
{
<button class="btn btn-secondary btn-sm" disabled><i class="fa-solid fa-trash"></i></button>
}
</td>
@* <AuthorizeView Roles="SuperAdmin, Admin, SuperUser">
<Authorized>
<td class="text-end">
@if (item.QtyTot == 0)
{
<button class="btn btn-danger btn-sm" @onclick="() => DeleteRecord(item)"><i class="fa-solid fa-trash"></i></button>
}
else
{
<button class="btn btn-secondary btn-sm" disabled><i class="fa-solid fa-trash"></i></button>
}
</td>
</Authorized>
</AuthorizeView> *@
</tr>
}
</tbody>
</table>
}
</div>
<div class="card-footer">
<EgwCoreLib.Razor.DataPager PageSize="@numRecord" currPage="@currPage" numRecordChanged="SetNumRec" numPageChanged="SetPage" totalCount="@totalCount" showLoading="@isLoading"></EgwCoreLib.Razor.DataPager>
</div>
</div>
@@ -0,0 +1,296 @@
using EgwCoreLib.Razor;
using GPW.CORE.Data.DbModels;
using GPW.CORE.Data.Services;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using Microsoft.VisualBasic.FileIO;
using NLog;
using Radzen;
using System;
using static EgwCoreLib.Razor.Toggler;
namespace GPW.CORE.ADM.Components.Compo
{
public partial class ClientiMan : IDisposable
{
#region Public Methods
public void Dispose()
{
AppMServ.EA_SearchUpdated -= AppMServ_EA_SearchUpdated;
}
#endregion Public Methods
#region Protected Properties
[Inject]
protected MessageService AppMServ { get; set; } = null!;
[Inject]
protected AppAuthService AuthServ { get; set; } = null!;
[Inject]
protected GpwDataService GDataServ { get; set; } = null!;
[Inject]
protected IJSRuntime JSRuntime { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected string CheckSel(AnagClientiModel curItem)
{
string answ = "";
if (SelItem != null)
{
answ = curItem.IdxCliente == SelItem.IdxCliente ? "table-info" : "";
}
// verifico stato attivo
answ += !curItem.Attivo ? " striked" : "";
return answ;
}
protected async Task CreateNew()
{
SelItem = new AnagClientiModel()
{
RagSociale = "__Nuovo cliente",
PIva = "0000000000000000",
Cf = "0000000000000000",
Nota = $"Nuovo cliente - {DateTime.Now}",
Attivo = true
};
await InvokeAsync(StateHasChanged);
}
protected async void DoDelete(AnagClientiModel selItem)
{
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Sicuro di voler eliminare il record?"))
return;
isLoading = true;
bool fatto = await GDataServ.AnagClientiDelete(selItem);
await ReloadData();
await InvokeAsync(StateHasChanged);
}
protected void DoEdit(AnagClientiModel? selItem)
{
SelItem = selItem;
}
protected async Task ForceReload(bool force)
{
SelItem = null;
await ReloadData();
}
protected override async Task OnInitializedAsync()
{
CurrSearch = "";
AppMServ.SearchVal = "";
AppMServ.EA_SearchUpdated += AppMServ_EA_SearchUpdated;
numRecord = await AppMServ.NumRowGridGet(gridKey);
ToggleData = new SelectGlobalToggle()
{
leftString = "Tutti",
rightString = "Solo Attivi",
placardCss = "border-dark"
};
}
protected override async Task OnParametersSetAsync()
{
await ReloadData();
}
protected async Task SetNumRec(int newNum)
{
numRecord = newNum;
currPage = 1;
await AppMServ.NumRowGridSet(gridKey, newNum);
await InvokeAsync(ReloadData);
}
protected async Task SetPage(int newNum)
{
currPage = newNum;
await InvokeAsync(ReloadData);
}
protected async Task SortRequested(Sorter.SortCallBack e)
{
sortField = e.ParamName;
sortAsc = e.IsAscending;
await ReloadData();
}
protected string Traduci(string lemma)
{
return AuthServ.Traduci(lemma, AppMServ.UserLang);
}
#endregion Protected Methods
#region Private Fields
private static Logger Log = LogManager.GetCurrentClassLogger();
private string gridKey = "ClientiMan";
private AnagClientiModel? SelItem = null;
private bool sortAsc = true;
private string sortField = "";
#endregion Private Fields
#region Private Properties
private int currPage { get; set; } = 1;
private string CurrSearch { get; set; } = "";
private bool isLoading { get; set; } = false;
private List<AnagClientiModel>? ListRecords { get; set; } = null;
private int numRecord { get; set; } = 10;
private List<AnagClientiModel>? SearchRecords { get; set; } = null;
private SelectGlobalToggle ToggleData { get; set; } = new SelectGlobalToggle();
private int totalCount { get; set; } = 0;
#endregion Private Properties
#region Private Methods
private async void AppMServ_EA_SearchUpdated()
{
CurrSearch = AppMServ.SearchVal;
await ReloadData();
await InvokeAsync(StateHasChanged);
}
private async Task evToggled(SelectGlobalToggle newTogData)
{
ToggleData = newTogData;
await ReloadData();
}
private async Task ReloadData()
{
isLoading = true;
ListRecords = null;
try
{
SearchRecords = await GDataServ.AnagClientiAll();
// verifico condizioni filtro
if (ToggleData.isActive)
{
SearchRecords = SearchRecords.Where(x => x.Attivo).ToList();
}
// verifico filtro per ricerca
if (!string.IsNullOrEmpty(CurrSearch))
{
SearchRecords = SearchRecords.Where(x => x.RagSociale.Contains(CurrSearch, StringComparison.InvariantCultureIgnoreCase)).ToList();
}
}
catch (Exception ex)
{
Log.Error($"Eccezione in recupero dati{Environment.NewLine}{ex}");
}
totalCount = SearchRecords.Count;
SortTable();
isLoading = false;
}
private void SortTable()
{
if (SearchRecords != null)
{
// se ho ordinamento riordino...
if (!string.IsNullOrEmpty(sortField))
{
switch (sortField)
{
case "RagSoc":
if (sortAsc)
{
SearchRecords = SearchRecords.OrderBy(x => x.RagSociale).ToList();
}
else
{
SearchRecords = SearchRecords.OrderByDescending(x => x.RagSociale).ToList();
}
break;
case "Indirizzo":
if (sortAsc)
{
SearchRecords = SearchRecords.OrderBy(x => x.Prov).ThenBy(x => x.Indirizzo).ToList();
}
else
{
SearchRecords = SearchRecords.OrderByDescending(x => x.Prov).ThenBy(x => x.Indirizzo).ToList();
}
break;
case "Contatti":
if (sortAsc)
{
SearchRecords = SearchRecords.OrderBy(x => x.Email).ThenBy(x => x.Tel).ToList();
}
else
{
SearchRecords = SearchRecords.OrderByDescending(x => x.Email).ThenBy(x => x.Tel).ToList();
}
break;
case "PICF":
if (sortAsc)
{
SearchRecords = SearchRecords.OrderBy(x => x.PIva).ToList();
}
else
{
SearchRecords = SearchRecords.OrderByDescending(x => x.PIva).ToList();
}
break;
case "Note":
if (sortAsc)
{
SearchRecords = SearchRecords.OrderBy(x => x.Nota).ToList();
}
else
{
SearchRecords = SearchRecords.OrderByDescending(x => x.Nota).ToList();
}
break;
case "Attivo":
if (sortAsc)
{
SearchRecords = SearchRecords.OrderBy(x => x.Attivo).ToList();
}
else
{
SearchRecords = SearchRecords.OrderByDescending(x => x.Attivo).ToList();
}
break;
default:
break;
}
}
// filtro x display
ListRecords = SearchRecords
.Skip(numRecord * (currPage - 1))
.Take(numRecord)
.ToList();
}
else
{
ListRecords = new List<AnagClientiModel>();
}
}
#endregion Private Methods
}
}
@@ -0,0 +1,10 @@
<div class="d-flex justify-content-between text-light">
<div class="text-start">
GPW <span class="small">v.@version</span>
</div>
<div class="text-end">
<span class="small px-1">@adesso</span>
<a class="text-light" href="https://www.egalware.com/" target="_blank"><img class="img-fluid" width="12" src="images/LogoEgw.png" /> Egalware </a>
</div>
</div>
@@ -0,0 +1,68 @@
namespace GPW.CORE.ADM.Components.Compo
{
public partial class CmpFooter : IDisposable
{
#region Public Methods
public void Dispose()
{
if (aTimer != null)
{
aTimer.Elapsed -= ElapsedTimer;
aTimer.Stop();
aTimer.Dispose();
}
}
#endregion Public Methods
#region Protected Fields
protected DateTime adesso = DateTime.Now;
#endregion Protected Fields
#region Protected Methods
protected void ElapsedTimer(object? source, System.Timers.ElapsedEventArgs e)
{
var pUpd = Task.Run(async () =>
{
adesso = DateTime.Now;
await InvokeAsync(StateHasChanged);
});
pUpd.Wait();
}
protected override void OnInitialized()
{
var rawVers = typeof(Program).Assembly.GetName().Version;
version = rawVers != null ? rawVers : new Version("0.0.0.0");
StartTimer();
}
protected void StartTimer()
{
if (aTimer != null)
{
aTimer.Stop();
aTimer.Dispose();
}
int tOutPeriod = 300000;
//int tOutPeriod = 1000;
aTimer = new System.Timers.Timer(tOutPeriod);
aTimer.Elapsed += ElapsedTimer;
aTimer.Enabled = true;
aTimer.Start();
}
#endregion Protected Methods
#region Private Fields
private System.Timers.Timer aTimer = null!;
private Version? version = null!;
#endregion Private Fields
}
}
@@ -0,0 +1,71 @@
<div class="card shadow">
<div class="card-header">
<h4>Dipendenti</h4>
<div class="row">
<div class="col-9">
<div class="input-group" runat="server">
<span class="input-group-text">Clona</span>
<select @bind="@idxDipSel" class="form-select form-select-sm">
<option value="0">--- Selezionare ---</option>
@foreach (var item in ListDipendenti)
{
<option value="@item.IdxDipendente">@($"{item.Cognome} {item.Nome}")</option>
}
</select>
@if (idxDipSel > 0)
{
<button class="btn btn-success" @onclick="AddSelected"><i class="fa fa-plus px-2" title="Aggiungi Assegnazione"></i></button>
}
</div>
</div>
<div class="col-3">
<div class="input-group">
<span class="input-group-text">Show Inatt.</span>
<span class="form-control">
<span class="form-check form-switch">
<input type="checkbox" class="form-check-input" @bind="@ShowInactive" @bind:after="ReloadData">
</span>
</span>
</div>
</div>
</div>
</div>
<div class="card-body p-1">
@if (ListRecords == null || isLoading)
{
<EgwCoreLib.Razor.LoadingData></EgwCoreLib.Razor.LoadingData>
}
else if (totalCount == 0)
{
<div class="alert alert-info">Nessun record trovato</div>
}
else
{
<table class="table table-striped table-sm text-start">
<thead>
<tr class="">
<th>Dipendente</th>
<th class="text-end"></th>
</tr>
</thead>
<tbody>
@foreach (var item in ListRecords)
{
<tr class="align-middle @CheckItem(item)">
<td>
<b>@item.Cognome</b> @item.Nome
</td>
<td class="text-end">
<button class="btn btn-danger btn-sm" @onclick="() => DoDelete(item)"><i class="fa-solid fa-trash"></i></button>
</td>
</tr>
}
</tbody>
</table>
}
</div>
<div class="card-footer">
<EgwCoreLib.Razor.DataPager PageSize="@numRecord" currPage="@currPage" numRecordChanged="SetNumRec" numPageChanged="SetPage" totalCount="@totalCount" showLoading="@isLoading"></EgwCoreLib.Razor.DataPager>
</div>
</div>
@@ -0,0 +1,183 @@
using GPW.CORE.Data.DbModels;
using GPW.CORE.Data.Services;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using NLog;
namespace GPW.CORE.ADM.Components.Compo
{
public partial class Dip2GrpMan : IDisposable
{
#region Public Properties
[Parameter]
public string CodGruppo { get; set; } = "";
#endregion Public Properties
#region Public Methods
public void Dispose()
{
AppMServ.EA_SearchUpdated -= AppMServ_EA_SearchUpdated;
}
#endregion Public Methods
#region Protected Properties
[Inject]
protected MessageService AppMServ { get; set; } = null!;
[Inject]
protected GpwDataService GDataServ { get; set; } = null!;
[Inject]
protected IJSRuntime JSRuntime { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected string CheckItem(DipendentiModel currItem)
{
string answ = !(currItem.Attivo ?? false) ? "striked" : "";
return answ;
}
protected async void DoDelete(DipendentiModel selItem)
{
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Sicuro di voler rimuovere il record di associazione dipendente/gruppo?"))
return;
isLoading = true;
await GDataServ.Dipendenti2GrpDelete(selItem.IdxDipendente, CodGruppo);
await ReloadData();
await InvokeAsync(StateHasChanged);
}
protected override async Task OnInitializedAsync()
{
CurrSearch = "";
AppMServ.SearchVal = "";
AppMServ.EA_SearchUpdated += AppMServ_EA_SearchUpdated;
numRecord = await AppMServ.NumRowGridGet(gridKey);
}
protected override async Task OnParametersSetAsync()
{
await ReloadData();
}
protected async Task SetNumRec(int newNum)
{
numRecord = newNum;
currPage = 1;
await AppMServ.NumRowGridSet(gridKey, newNum);
await InvokeAsync(ReloadData);
}
protected async Task SetPage(int newNum)
{
currPage = newNum;
await InvokeAsync(ReloadData);
}
#endregion Protected Methods
#region Private Fields
private static Logger Log = LogManager.GetCurrentClassLogger();
private string gridKey = "Dip2GrpMan";
private int idxDipSel = 0;
private bool showInactive = false;
#endregion Private Fields
#region Private Properties
private int currPage { get; set; } = 1;
private string CurrSearch { get; set; } = "";
private bool isLoading { get; set; } = false;
private List<DipendentiModel> ListDipendenti { get; set; } = new List<DipendentiModel>();
private List<DipendentiModel>? ListRecords { get; set; } = null;
private int numRecord { get; set; } = 10;
private List<DipendentiModel>? SearchRecords { get; set; } = null;
private bool ShowInactive
{
get => showInactive;
set { showInactive = value; }
}
private int totalCount { get; set; } = 0;
#endregion Private Properties
#region Private Methods
private async void AppMServ_EA_SearchUpdated()
{
CurrSearch = AppMServ.SearchVal;
await ReloadData();
await InvokeAsync(StateHasChanged);
}
private async Task ReloadData()
{
isLoading = true;
ListRecords = null;
ListDipendenti = await GDataServ.DipendentiGetAll();
try
{
SearchRecords = await GDataServ.DipendentiByGrp(CodGruppo);
// tolgo da el associabili quelli già associati...
ListDipendenti = ListDipendenti.Where(i => !SearchRecords.Contains(i)).ToList();
// verifico filtro per ricerca
if (!string.IsNullOrEmpty(CurrSearch))
{
SearchRecords = SearchRecords.Where(x => x.Cognome.Contains(CurrSearch, StringComparison.InvariantCultureIgnoreCase) || x.Nome.Contains(CurrSearch, StringComparison.InvariantCultureIgnoreCase)).ToList();
}
if (!showInactive)
{
SearchRecords = SearchRecords.Where(x => x.Attivo ?? false).ToList();
ListDipendenti = ListDipendenti.Where(x => x.Attivo ?? false).ToList();
}
}
catch (Exception ex)
{
Log.Error($"Eccezione in recupero dati{Environment.NewLine}{ex}");
}
totalCount = SearchRecords.Count;
// filtro x display
ListRecords = SearchRecords
.OrderBy(x => x.Cognome)
.ThenBy(x => x.Nome)
.Skip(numRecord * (currPage - 1))
.Take(numRecord)
.ToList();
// cerco i dip del gruppo...
isLoading = false;
}
private async Task AddSelected()
{
await GDataServ.Dipendenti2GrpInsert(idxDipSel, CodGruppo);
await ReloadData();
}
#endregion Private Methods
}
}
@@ -0,0 +1,93 @@
<div class="row g-1">
<div class="col-md-3">
<div class="form-floating">
<input type="text" class="form-control" @bind="@CurrRecord.NomeFase">
<label class="small">Nome</label>
</div>
</div>
<div class="col-md-2">
<div class="form-floating">
<div class="form-control">
<select @bind="@CurrRecord.CodTagFase" class="form-select form-select-sm" title="Tag">
<option value="">--- Selezionare ---</option>
@foreach (var item in ListTagFasi)
{
<option value="@item.CodTagFase">@($"[{item.CodTagFase}] {item.Descrizione}")</option>
}
</select>
</div>
<label class="small">Tag</label>
</div>
</div>
<div class="col-md-1">
<div class="form-floating">
<div class="form-control">
<div class="form-check form-switch">
<input type="checkbox" class="form-check-input" @bind="@CurrRecord.EnableTime">
</div>
</div>
<label class="small">Time</label>
</div>
</div>
<div class="col-md-1">
<div class="form-floating">
<div class="form-control">
<div class="form-check form-switch">
<input type="checkbox" class="form-check-input" @bind="@CurrRecord.EnableMoney">
</div>
</div>
<label class="small">Money</label>
</div>
</div>
<div class="col-md-2">
<div class="form-floating">
@if (CurrRecord.IdxFaseAncest == 0)
{
<input type="number" class="form-control" @bind="@CurrRecord.BudgetTime" disabled>
}
else
{
<input type="number" class="form-control" @bind="@CurrRecord.BudgetTime">
}
<label class="small">Ore Bdgt</label>
</div>
</div>
<div class="col-md-2">
<div class="form-floating">
@if (CurrRecord.IdxFaseAncest == 0)
{
<input type="number" min="0" max="100" step="0.1" class="form-control" @bind="@CurrRecord.PercOpenCent">
}
else
{
<input type="number" class="form-control" @bind="@CurrRecord.PercOpenCent" disabled>
}
<label class="small">% abil</label>
</div>
</div>
<div class="col-md-1">
<div class="form-floating">
<div class="form-control">
<div class="form-check form-switch">
<input type="checkbox" class="form-check-input" @bind="@CurrRecord.Attivo">
</div>
</div>
<label class="small">Attivo</label>
</div>
</div>
</div>
<div class="row g-1">
<div class="col-md-10">
<div class="form-floating">
<textarea class="form-control" @bind="@CurrRecord.DescrizioneFase" rows="2" style="height: 9rem;"></textarea>
<label class="small">Descr</label>
</div>
</div>
<div class="col-md-2 pt-2 d-flex align-items-center">
<div class="w-100">
<button class="btn btn-success my-1 w-100" @onclick="() => DoSave()"><i class="fas fa-floppy-disk"></i> Save</button>
<button class="btn btn-warning my-1 w-100" @onclick="() => DoCancel()"><i class="fas fa-ban"></i> Cancel</button>
</div>
</div>
</div>
@@ -0,0 +1,55 @@
using GPW.CORE.Data.DbModels;
using GPW.CORE.Data.DTO;
using GPW.CORE.Data.Services;
using Microsoft.AspNetCore.Components;
namespace GPW.CORE.ADM.Components.Compo
{
public partial class FasiEdit
{
#region Public Properties
[Parameter]
public AnagFasiModel? CurrRecord { get; set; } = null;
[Parameter]
public EventCallback<bool> EC_update { get; set; }
[Parameter]
public List<TagFasiDTO> ListTagFasi { get; set; } = null!;
#endregion Public Properties
#region Protected Properties
[Inject]
protected GpwDataService GDataServ { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected async Task DoCancel()
{
await EC_update.InvokeAsync(true);
}
protected async Task DoSave()
{
bool fatto = false;
await Task.Delay(1);
if (CurrRecord != null)
{
fatto = await GDataServ.AnagFasiUpsert(CurrRecord);
// se fatto ricalcolo...
if (fatto)
{
await GDataServ.AnagProjForceUpdate();
}
}
await EC_update.InvokeAsync(fatto);
}
#endregion Protected Methods
}
}
+227
View File
@@ -0,0 +1,227 @@
@if (RecordEdit != null)
{
<div class="modal fade show" tabindex="-1" style="display:block; background-color: rgba(10,10,10,.6);" aria-modal="true" role="dialog" data-keyboard="true">
<div class="modal-dialog modal-xl">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Modifica Fase <b>@RecordEdit.IdxFase</b></h4>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" @onclick=ForceReload></button>
</div>
<div class="modal-body p-1">
<FasiEdit CurrRecord=@RecordEdit EC_update=ForceReload ListTagFasi=@ListTagFasi></FasiEdit>
</div>
</div>
</div>
</div>
}
<div class="card">
<div class="card-header @HeadCss">
<div class="d-flex justify-content-between">
@if (CanSelProj)
{
@if (!string.IsNullOrEmpty(Title))
{
<div class="ps-0 pe-2">
<h4>@Title</h4>
</div>
}
<div class="px-0">
<div class="px-0 d-flex">
<div class="px-0">
<div class="input-group">
<span class="input-group-text" title="Cliente">C</span>
<select @bind="@IdxCli" class="form-select form-select-sm" title="Cliente" @bind:after=SaveCli>
<option value="0">--- Selezionare ---</option>
@foreach (var item in ListClienti)
{
<option value="@item.IdxCliente">@($"{item.RagSociale}")</option>
}
</select>
</div>
</div>
<div class="px-0">
<div class="input-group">
<span class="input-group-text" title="Progetto">P</span>
<select @bind="@IdxPrj" class="form-select form-select-sm" title="Progetto" @bind:after=SaveProj>
<option value="0">--- Selezionare ---</option>
@foreach (var item in ListProgetti)
{
<option value="@item.IdxProgetto">@($"{item.NomeProj} | {item.DescrProj}")</option>
}
</select>
</div>
</div>
</div>
</div>
}
else
{
<div class="px-0">
<h4>Dettaglio Fasi</h4>
</div>
<div class="px-0">
<div class="input-group">
<span class="input-group-text">Tag</span>
<select @bind="@NewCodTagFase" class="form-select form-select-sm" title="Tag">
<option value="">--- Selezionare ---</option>
@foreach (var item in ListTagFasi)
{
<option value="@item.CodTagFase">@($"[{item.CodTagFase}] {item.Descrizione}")</option>
}
</select>
<button class="btn btn-danger text-nowrap" @onclick=DoMassTagUpd>
<i class="fa-solid fa-circle-left"></i> Force SET All
</button>
</div>
</div>
}
</div>
</div>
<div class="card-body p-1">
@if (ListRecords == null || isLoading)
{
<EgwCoreLib.Razor.LoadingData></EgwCoreLib.Razor.LoadingData>
}
else if (totalCount == 0)
{
<div class="alert alert-info">Nessun record trovato</div>
}
else
{
<table class="table table-striped table-sm text-start small">
<thead>
<tr class="">
<th>
<button class="btn btn-primary btn-sm" @onclick="ForceReload"><i class="fa-solid fa-rotate"></i></button>
</th>
<th>Nome</th>
<th>Etichetta Fase</th>
<th>TT</th>
<th>MT</th>
<th>Ore/Budget</th>
<th>% Abil</th>
<th>Attivo</th>
@if (!CanSelProj)
{
<th class="text-end">
@if (ChkLicOk)
{
<button class="btn btn-success btn-sm" @onclick="() => AddFase(0)"><i class="fa-solid fa-plus"></i> Nuova Fase</button>
}
</th>
<th class="text-end" style="width: 3rem;"></th>
}
</tr>
</thead>
<tbody>
@foreach (var item in ListRecords)
{
<tr class="align-middle @CheckSel(item)">
<td>
@if (ShowSelect)
{
<button class="btn btn-info btn-sm" @onclick="() => DoSelect(item)"><i class="fa-solid fa-search"></i></button>
}
@if (RecordSel == null)
{
@if (!CanSelProj)
{
<button class="btn btn-primary btn-sm" @onclick="() => DoEdit(item)"><i class="fa-solid fa-edit"></i></button>
}
}
else
{
@if (!CanSelProj)
{
<button class="btn btn-secondary btn-sm" disabled><i class="fa-solid fa-edit"></i></button>
}
}
</td>
<td>
<div class="d-flex">
@if (item.IdxFaseAncest > 0)
{
<div class="px-2"><i class="fa-solid fa-ellipsis-vertical"></i></div>
}
<div class="px-2">
<b>@item.NomeFase</b>
<div class="small">@item.DescrizioneFase</div>
</div>
</div>
</td>
<td>
@if (item.IdxFaseAncest > 0)
{
<select @bind="@item.CodTagFase" class="form-select form-select-sm" title="Cliente" disabled style="width: 12rem;">
<option value="0">--- Selezionare ---</option>
@foreach (var iTag in ListTagFasi)
{
<option value="@iTag.CodTagFase">@($"[{iTag.CodTagFase}] {iTag.Descrizione}")</option>
}
</select>
}
</td>
<td class="fs-4">
@if (item.EnableTime)
{
<i class="fa-solid fa-stopwatch text-primary"></i>
}
else
{
<i class="fa-solid fa-stopwatch text-secondary opacity-50"></i>
}
</td>
<td>
@if (item.EnableMoney)
{
<i class="fa-solid fa-money-bills text-primary"></i>
}
else
{
<i class="fa-solid fa-money-bills text-secondary opacity-50"></i>
}
</td>
<td>
@if (item.BudgetTime > 0)
{
<div class="text-center py-1 @ColorByVal(item.TotOre, item.BudgetTime)">
<b>@($"{item.TotOre:N2}")</b> / @($"{item.BudgetTime:N0}")
</div>
}
</td>
<td>
@if (item.IdxFaseAncest == 0)
{
@($"{item.PercOpen:P0}")
}
</td>
<td>
<div class="form-check">
<input class="form-check-input" disabled type="checkbox" @bind="@item.Attivo">
</div>
</td>
@if (!CanSelProj)
{
<td class="text-end">
@if (item.IdxFaseAncest == 0 && EnableAddFasi && ChkLicOk)
{
<button class="btn btn-primary btn-sm" @onclick="() => AddFase(item.IdxFase)"><i class="fa-solid fa-plus"></i> Nuova Sottofase</button>
}
</td>
<td class="text-end">
@if (DelEnabled(item.TotOre, item.IdxFase, item.IdxFaseAncest) && ChkLicOk)
{
<button class="btn btn-danger btn-sm" @onclick="() => DoDelete(item)"><i class="fa-solid fa-trash"></i></button>
}
</td>
}
</tr>
}
</tbody>
</table>
}
</div>
</div>
@@ -0,0 +1,378 @@
using GPW.CORE.Data.DbModels;
using GPW.CORE.Data.DTO;
using GPW.CORE.Data.Services;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.JSInterop;
using NLog.Targets.Wrappers;
namespace GPW.CORE.ADM.Components.Compo
{
public partial class FasiMan
{
#region Public Properties
[Parameter]
public bool CanSelProj { get; set; } = false;
[Parameter]
public bool ChkLicOk { get; set; } = true;
[Parameter]
public EventCallback<AnagFasiExplModel> EC_FaseSel { get; set; }
[Parameter]
public EventCallback<int> EC_ProjSel { get; set; }
[Parameter]
public EventCallback<bool> EC_update { get; set; }
[Parameter]
public bool EnableAddFasi { get; set; } = true;
[Parameter]
public string HeadCss { get; set; } = "";
[Parameter]
public List<AnagFasiExplModel>? ListRecords
{
get => listRecords;
set => listRecords = value;
}
[Parameter]
public bool ShowOnlyActive { get; set; } = true;
[Parameter]
public bool ShowSelect { get; set; } = true;
[Parameter]
public string Title { get; set; } = "";
#endregion Public Properties
#region Protected Properties
[Inject]
protected MessageService AppMServ { get; set; } = null!;
[Inject]
protected GpwDataService GDataServ { get; set; } = null!;
protected int IdxCli
{
get => idxCli;
set
{
if (idxCli != value)
{
idxCli = value;
}
}
}
protected int IdxPrj
{
get => idxPrj;
set
{
if (idxPrj != value)
{
idxPrj = value;
}
}
}
[Inject]
protected IJSRuntime JSRuntime { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
/// <summary>
/// Aggiunta nuova fase/sottofase (se idxFaseAnc &gt; 0)
/// </summary>
/// <param name="idxFaseAnc"></param>
/// <returns></returns>
protected async Task AddFase(int idxFaseAnc)
{
int idxProj = 0;
if (ListRecords != null && ListRecords.Count > 0)
{
idxProj = ListRecords.FirstOrDefault().IdxProgetto ?? 0;
}
if (idxProj > 0)
{
// creo nuovo record...
var newRec = new AnagFasiModel()
{
IdxProgetto = idxProj,
IdxFaseAncest = idxFaseAnc,
NomeFase = "__Nuova Fase",
DescrizioneFase = "Descrizione Fase"
};
// eseguo aggiunta nuovo record...
bool fatto = await GDataServ.AnagFasiUpsert(newRec);
if (fatto)
{
await EC_update.InvokeAsync(true);
}
}
}
protected string CheckSel(AnagFasiExplModel curItem)
{
string answ = "";
if (RecordSel != null)
{
answ = curItem.IdxFase == RecordSel.IdxFase ? "table-info" : "";
}
// verifico stato attivo
answ += !curItem.Attivo ? " striked" : "";
return answ;
}
protected async Task DoDelete(AnagFasiExplModel? selItem)
{
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Sicuro di voler forzare il ricalcolo dei record?"))
return;
if (selItem != null)
{
bool fatto = await GDataServ.AnagFasiDelete(selItem.IdxFase);
if (fatto)
{
await EC_update.InvokeAsync(true);
}
}
}
protected async Task DoEdit(AnagFasiExplModel? selItem)
{
RecordSel = null;
if (selItem != null)
{
RecordEdit = await GDataServ.AnagFasiByKey(selItem.IdxFase);
}
else
{
RecordEdit = null;
}
}
protected async Task DoMassTagUpd()
{
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Sicuro di voler forzare il tag per tutte le fasi?"))
return;
int idxProj = 0;
if (ListRecords != null && ListRecords.Count > 0)
{
idxProj = ListRecords.FirstOrDefault().IdxProgetto ?? 0;
if (idxProj > 0)
{
bool fatto = await GDataServ.AnagFasiForceTag(idxProj, NewCodTagFase);
if (fatto)
{
await EC_update.InvokeAsync(true);
}
}
}
}
protected async Task DoSelect(AnagFasiExplModel? selItem)
{
RecordSel = selItem;
RecordEdit = null;
await EC_FaseSel.InvokeAsync(selItem);
}
protected async Task ForceReload()
{
RecordEdit = null;
RecordSel = null;
await EC_FaseSel.InvokeAsync(null);
await EC_update.InvokeAsync(true);
await Task.Delay(1);
isLoading = false;
}
/// <summary>
/// init valori da config
/// </summary>
/// <returns></returns>
protected async Task InitConf()
{
// leggo conf standard controllo RegAtt
var sWarningRatioPerc = await GDataServ.ConfigGetKey("WarningRatioPerc");
if (sWarningRatioPerc != null)
{
double.TryParse(sWarningRatioPerc.valore, out warnRatio);
}
}
protected override async Task OnInitializedAsync()
{
await InitConf();
await ReloadSel();
await ReloadData();
}
protected override async Task OnParametersSetAsync()
{
await ReloadData();
}
/// <summary>
/// Tentativo rilettura selezione se possibile..
/// </summary>
/// <returns></returns>
protected async Task ReloadSel()
{
// verifico di essere in modalità con selezione permessa x preselezione
if (CanSelProj)
{
IdxCli = await AppMServ.UserPrefGet<int>($"FasiMan_{Title}_idxCli");
IdxPrj = await AppMServ.UserPrefGet<int>($"FasiMan_{Title}_idxPrj");
await EC_ProjSel.InvokeAsync(IdxPrj);
}
}
#endregion Protected Methods
#region Private Fields
private string gridKey = "FasiMan";
private int idxCli = 0;
private int idxPrj = 0;
private AnagFasiModel? RecordEdit = null;
private AnagFasiExplModel? RecordSel = null;
private double warnRatio = 50;
#endregion Private Fields
#region Private Properties
private bool isLoading { get; set; } = false;
private List<AnagClientiModel> ListClienti { get; set; } = new List<AnagClientiModel>();
private List<AnagProgettiModel> ListProgetti { get; set; } = new List<AnagProgettiModel>();
private List<AnagFasiExplModel>? listRecords { get; set; } = new List<AnagFasiExplModel>();
private List<TagFasiDTO> ListTagFasi { get; set; } = new List<TagFasiDTO>();
private string NewCodTagFase { get; set; } = "ND";
private int totalCount { get; set; } = 0;
#endregion Private Properties
#region Private Methods
/// <summary>
/// restituisce una classe css a seconda dei valori passati:
/// green: bdgt &gt; real
/// orange: real &gt; bdgt*warning
/// red: real &gt; bdgt
/// std: errore...
/// </summary>
/// <param name="real"></param>
/// <param name="bdgt"></param>
/// <returns></returns>
private string ColorByVal(object real, object bdgt)
{
string specClass = "default";
try
{
double valoreReal = Convert.ToDouble(real);
double valoreBdget = Convert.ToDouble(bdgt);
double valoreWarn = Convert.ToDouble(bdgt) * warnRatio / 100;
if (valoreReal >= valoreBdget)
{
specClass = "danger";
}
else if (valoreReal >= valoreWarn)
{
specClass = "warning";
}
else
{
specClass = "success";
}
}
catch
{ }
return $" bg-{specClass} bg-opacity-50 bg-gradient border border-{specClass} rounded";
}
private bool DelEnabled(decimal TotOre, int idxFase, int idxFaseAnc)
{
// se ha ore NON è eliminabile...
bool answ = TotOre == 0;
// se zero ore --> deve esere child oppure ancestor senza fasi...
if (answ)
{
// se ancestor
if (idxFaseAnc == 0)
{
// cerco fasi dato ancestor...
var listChild = GDataServ.AnagFasiByAncestor(idxFase);
// solo se NON ha fasi child
answ = listChild == null || listChild.Count == 0;
}
}
return answ;
}
private async Task ReloadData()
{
ListTagFasi = await GDataServ.AnagTagFasiAll();
if (CanSelProj)
{
listRecords = new List<AnagFasiExplModel>();
ListProgetti = new List<AnagProgettiModel>();
ListClienti = await GDataServ.AnagClientiAll();
if (ShowOnlyActive)
{
ListClienti = ListClienti.Where(x => x.Attivo).ToList();
}
// seleziono proj da client
if (IdxCli > 0)
{
ListProgetti = await GDataServ.AnagProjByCli(IdxCli);
if (ShowOnlyActive)
{
ListProgetti = ListProgetti.Where(x => x.Attivo ?? false).ToList();
}
}
// se abilitato x rilettura locale --> leggo fasi!
if (CanSelProj && IdxCli > 0 && IdxPrj > 0)
{
listRecords = await GDataServ.AnagFasiExplByProj(IdxPrj);
}
}
totalCount = listRecords.Count;
isLoading = false;
}
private async Task SaveCli()
{
IdxPrj = 0;
await ReloadData();
await EC_ProjSel.InvokeAsync(IdxPrj);
await SaveSelection();
}
private async Task SaveProj()
{
await ReloadData();
await EC_ProjSel.InvokeAsync(IdxPrj);
await SaveSelection();
}
private async Task SaveSelection()
{
await AppMServ.UserPrefSet($"FasiMan_{Title}_idxCli", $"{IdxCli}");
await AppMServ.UserPrefSet($"FasiMan_{Title}_idxPrj", $"{IdxPrj}");
}
#endregion Private Methods
}
}
@@ -0,0 +1,99 @@
<div class="card shadow">
<div class="card-header">
<div class="d-flex justify-content-between">
<div class="px-0">
<h5>Giustificativi</h5>
</div>
<div class="px-0">
@if (ListRecord == null || ListRecord.Count == 0)
{
<button class="btn btn-sm btn-success" @onclick="DoAddNew"><i class="fa-solid fa-plus"></i> Add New</button>
}
</div>
</div>
</div>
<div class="card-body py-0 px-2">
@if (ListRecord == null || ListRecord.Count == 0)
{
<div class="alert alert-info py-1 px-2 my-1 mx-0">
<div class="d-flex justify-content-between">
Nessun record trovato
</div>
</div>
}
else
{
<table class="table table-sm table-striped table-responsive-md">
<thead>
<tr>
<th></th>
<th><i class="fa-solid fa-stopwatch"></i></th>
<th title="Giust">Cod.Giust.</th>
<th>Min:</th>
<th class="text-end">
<button class="btn btn-sm btn-success" @onclick="DoAddNew"><i class="fa-solid fa-plus"></i> Add New</button>
</th>
</tr>
</thead>
<tbody>
@if (SelRecord != null)
{
<tr>
<td>
<button class="btn btn-success btn-sm" @onclick="DoSave" title="Save"><i class="fa-solid fa-floppy-disk"></i></button>
</td>
<td class="small">@($"{SelRecord.DataLav:yyyy.MM.dd}")</td>
<td class="text-center">
<select @bind="@SelRecord.CodGiust" class="form-select">
<option value="">--- Selezionare Causale ---</option>
@if (ListGiust != null)
{
@foreach (var giust in ListGiust)
{
<option value="@giust.codGiust">@giust.descrizione</option>
}
}
</select>
</td>
<td title="Uscita" class="text-center">
<input type="number" class="form-control" @bind="@SelRecord.Minuti" />
</td>
<td class="text-end">
<button class="btn btn-sm btn-warning" @onclick="DoCancel" title="Cancel"><i class="fas fa-ban"></i></button>
</td>
</tr>
}
else
{
@foreach (var item in ListRecord)
{
<tr>
<td>
<button class="btn btn-primary btn-sm" @onclick="() => DoEdit(item)"><i class="fa-solid fa-edit"></i></button>
</td>
<td class="small">@($"{item.DataLav:yyyy.MM.dd}")</td>
<td class="text-center">
@item.CodGiust
</td>
<td title="Uscita" class="text-center">
@item.Minuti
</td>
<td class="text-end">
@if (EnableDelete)
{
<button class="btn btn-sm btn-danger" @onclick="() => DoDelete(item)" title="Elimina Timbratura"><i class="fas fa-trash-alt"></i></button>
}
else
{
<button class="btn btn-sm btn-secondary" disabled><i class="fas fa-trash-alt"></i></button>
}
</td>
</tr>
}
}
</tbody>
</table>
}
</div>
</div>
@@ -0,0 +1,139 @@
using GPW.CORE.Data.DbModels;
using Microsoft.AspNetCore.Components;
namespace GPW.CORE.ADM.Components.Compo
{
public partial class GiustList
{
#region Public Properties
[Parameter]
public EventCallback<string> EC_ReqAddNew { get; set; }
[Parameter]
public EventCallback<bool> EC_ReqCancel { get; set; }
[Parameter]
public EventCallback<GiustificativiModel> EC_ReqDelete { get; set; }
[Parameter]
public EventCallback<GiustSet> EC_ReqUpdate { get; set; }
[Parameter]
public bool EnableDelete { get; set; } = false;
[Parameter]
public bool EnableEdit { get; set; } = false;
[Parameter]
public List<AnagGiustModel>? ListGiust { get; set; } = null;
[Parameter]
public List<GiustificativiModel>? ListRecord
{
get => listTimb;
set => listTimb = value;
}
#endregion Public Properties
#region Public Structs
public struct GiustSet
{
#region Public Properties
public GiustificativiModel NewRec { get; set; }
public GiustificativiModel OldRec { get; set; }
#endregion Public Properties
}
#endregion Public Structs
#region Protected Properties
protected List<GiustificativiModel>? listTimb
{
get
{
return _ListTimb;
}
set
{
if (value != null)
{
_ListTimb = value.OrderByDescending(x => x.DataLav).ToList();
}
else
{
_ListTimb = null;
}
}
}
#endregion Protected Properties
#region Protected Methods
protected async Task DoAddNew()
{
await EC_ReqAddNew.InvokeAsync("PERM");
}
protected async void DoCancel()
{
await EC_ReqCancel.InvokeAsync(true);
}
protected async void DoDelete(GiustificativiModel currRecord)
{
await EC_ReqDelete.InvokeAsync(currRecord);
}
protected void DoEdit(GiustificativiModel SelRec)
{
SelRecord = SelRec;
OldRecord = new GiustificativiModel()
{
Automatico = SelRec.Automatico,
CodGiust = SelRec.CodGiust,
DataLav = SelRec.DataLav,
IdxDipendente = SelRec.IdxDipendente,
Minuti = SelRec.Minuti
};
}
protected async void DoSave()
{
if (OldRecord != null && SelRecord != null)
{
GiustSet newSet = new GiustSet()
{
OldRec = OldRecord,
NewRec = SelRecord
};
OldRecord = null;
SelRecord = null;
await EC_ReqUpdate.InvokeAsync(newSet);
}
}
protected override async Task OnParametersSetAsync()
{
await InvokeAsync(StateHasChanged);
}
#endregion Protected Methods
#region Private Properties
private List<GiustificativiModel>? _ListTimb { get; set; } = new List<GiustificativiModel>();
private GiustificativiModel? OldRecord { get; set; } = null;
private GiustificativiModel? SelRecord { get; set; } = null;
#endregion Private Properties
}
}
@@ -0,0 +1,36 @@
<div class="row g-1">
<div class="col-md-6">
<div class="form-floating">
<input type="text" class="form-control" @bind="@CurrRecord.Gruppo">
<label class="small">Gruppo</label>
</div>
</div>
<div class="col-md-2">
<div class="form-floating">
<input type="text" class="form-control" @bind="@CodExt">
<label class="small">Cod Ext. (4 chr)</label>
</div>
</div>
<div class="col-md-1">
<div class="form-floating">
<span class="form-control">
<div class="form-check form-switch">
<input type="checkbox" class="form-check-input" @bind="@CurrRecord.ExportEnab">
</div>
</span>
<label class="small">Exp. Abil</label>
</div>
</div>
<div class="col-md-3">
<button class="btn btn-success btn-lg mt-2 w-100" @onclick="() => DoSave()"><i class="fas fa-floppy-disk"></i> Save</button>
</div>
<div class="col-md-9 my-2">
<div class="form-floating">
<input type="text" class="form-control" @bind="@CurrRecord.DescrGruppo">
<label class="small">Descrizione</label>
</div>
</div>
<div class="col-md-3">
<button class="btn btn-warning btn-lg mt-2 w-100" @onclick="() => DoCancel()"><i class="fas fa-ban"></i> Cancel</button>
</div>
</div>
@@ -0,0 +1,55 @@
using GPW.CORE.Data.DbModels;
using GPW.CORE.Data.DTO;
using GPW.CORE.Data.Services;
using Microsoft.AspNetCore.Components;
namespace GPW.CORE.ADM.Components.Compo
{
public partial class GruppiEdit
{
#region Public Properties
[Parameter]
public AnagGruppiModel? CurrRecord { get; set; } = null;
[Parameter]
public EventCallback<bool> EC_update { get; set; }
#endregion Public Properties
#region Protected Properties
[Inject]
protected GpwDataService GDataServ { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected string CodExt
{
get => CurrRecord.CodExt ?? "";
set
{
CurrRecord.CodExt = value.Length < 5 ? value : value.Substring(0, 4);
}
}
protected async Task DoSave()
{
bool fatto = false;
if (CurrRecord != null)
{
fatto = await GDataServ.AnagGruppiUpsert(CurrRecord);
}
await EC_update.InvokeAsync(fatto);
}
protected async Task DoCancel()
{
await EC_update.InvokeAsync(true);
}
#endregion Protected Methods
}
}
@@ -0,0 +1,169 @@
@if (SelItem != null && isEdit)
{
<div class="modal fade show" tabindex="-1" style="display:block; background-color: rgba(10,10,10,.6);" aria-modal="true" role="dialog" data-keyboard="true">
<div class="modal-dialog modal-xl">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Edit Gruppo <b>@SelItem.Gruppo</b></h4>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" @onclick="() => ForceReload(true)"></button>
</div>
<div class="modal-body p-1">
<GruppiEdit CurrRecord="@SelItem" EC_update="ForceReload"></GruppiEdit>
</div>
</div>
</div>
</div>
}
<div class="card shadow">
<div class="card-header">
<div class="d-flex justify-content-between">
<div class="px-0 d-flex">
<div class="px-2">
<h3>Gestione Gruppi/Dipendenti</h3>
</div>
</div>
<div class="px-0">
<div class="input-group" runat="server">
<span class="input-group-text">Clona</span>
<select @bind="@idxDipFrom" class="form-select form-select-sm">
<option value="0">--- Selezionare ---</option>
@foreach (var item in ListDipendenti)
{
<option value="@item.IdxDipendente">@($"{item.Cognome} {item.Nome}")</option>
}
</select>
@if (idxDipFrom > 0 && idxDipTo > 0)
{
<button class="btn btn-success"><i class="fa fa-angle-double-right px-2" title="Clona Assegnazioni" @onclick="ClonaAssegnDip"></i></button>
}
else
{
<button class="btn btn-secondary" disabled><i class="fa fa-angle-double-right px-2" title="Clona Assegnazioni"></i></button>
}
<select @bind="@idxDipTo" class="form-select form-select-sm">
<option value="0">--- Selezionare ---</option>
@foreach (var item in ListDipendenti.Where(x => (x.Attivo ?? false)).ToList())
{
<option value="@item.IdxDipendente">@($"{item.Cognome} {item.Nome}")</option>
}
</select>
@if (idxDipFrom > 0 || idxDipTo > 0)
{
<button class="btn btn-primary" @onclick="DoResetSelClona"><i class="fa-solid fa-rotate px-1" title="Reset"></i></button>
}
else
{
<button class="btn btn-secondary" disabled><i class="fa-solid fa-rotate px-1" title="Reset"></i></button>
}
</div>
</div>
</div>
</div>
<div class="card-body p-1">
<div class="row">
<div class="col-7">
<div class="card shadow">
<div class="card-header">
<div class="px-0 d-flex">
<div class="px-2">
<h4>Gruppi</h4>
</div>
<div class="px-2">
<button class="btn btn-success" @onclick=CreateNew tooltip="Add New"><i class="fa-solid fa-plus"></i> Add New</button>
</div>
</div>
</div>
<div class="card-body p-1">
@if (ListRecords == null || isLoading)
{
<EgwCoreLib.Razor.LoadingData></EgwCoreLib.Razor.LoadingData>
}
else if (totalCount == 0)
{
<div class="alert alert-info">Nessun record trovato</div>
}
else
{
<table class="table table-striped table-sm text-start">
<thead>
<tr class="">
<th class="text-nowrap">
<button class="btn btn-primary btn-sm" @onclick="() => ForceReload(true)"><i class="fa-solid fa-rotate"></i></button>
</th>
<th>Gruppo <Sorter ParamName="CodGruppo" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
<th>Descrizione <Sorter ParamName="Descrizione" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
<th>CodExt Grp. <Sorter ParamName="CodExt" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
<th># Dip. <Sorter ParamName="NumDip" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
<th class="text-end"><Sorter ParamName="Export" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter> Exp. Abil</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in ListRecords)
{
<tr class="align-middle @CheckSel(item)">
<td class="text-nowrap">
<button class="btn btn-info btn-sm" @onclick="() => DoSelect(item)"><i class="fa-solid fa-search"></i></button>
@if (SelItem == null)
{
<button class="btn btn-primary btn-sm mx-1" @onclick="() => DoEdit(item)">
<i class="fa-solid fa-edit"></i>
</button>
}
else
{
<button class="btn btn-secondary btn-sm mx-1" disabled><i class="fa-solid fa-edit"></i></button>
}
</td>
<td>
@item.Gruppo
</td>
<td>
@item.DescrGruppo
</td>
<td>
@item.NumDip
</td>
<td>
@item.CodExt
</td>
<td class="text-end">
<input class="form-check-input" type="checkbox" disabled role="switch" @bind="@item.ExportEnab">
</td>
<td>
@if (@item.NumDip == 0)
{
<button class="btn btn-danger btn-sm" @onclick="() => DoDelete(item)"><i class="fa-solid fa-trash"></i></button>
}
else
{
<button class="btn btn-secondary btn-sm" disabled><i class="fa-solid fa-trash"></i></button>
}
</td>
</tr>
}
</tbody>
</table>
}
</div>
<div class="card-footer">
<EgwCoreLib.Razor.DataPager PageSize="@numRecord" currPage="@currPage" numRecordChanged="SetNumRec" numPageChanged="SetPage" totalCount="@totalCount" showLoading="@isLoading"></EgwCoreLib.Razor.DataPager>
</div>
</div>
</div>
<div class="col-5">
@if (SelItem != null)
{
<Dip2GrpMan CodGruppo="@SelItem.Gruppo"></Dip2GrpMan>
}
else
{
<div class="alert alert-info p-3 my-5">Selezionare gruppo per visualizzare dipendenti associati</div>
}
</div>
</div>
</div>
</div>
@@ -0,0 +1,268 @@
using EgwCoreLib.Razor;
using GPW.CORE.Data.DbModels;
using GPW.CORE.Data.DTO;
using GPW.CORE.Data.Services;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using NLog;
namespace GPW.CORE.ADM.Components.Compo
{
public partial class GruppiMan : IDisposable
{
#region Public Methods
public void Dispose()
{
AppMServ.EA_SearchUpdated -= AppMServ_EA_SearchUpdated;
}
#endregion Public Methods
#region Protected Properties
[Inject]
protected MessageService AppMServ { get; set; } = null!;
[Inject]
protected GpwDataService GDataServ { get; set; } = null!;
[Inject]
protected IJSRuntime JSRuntime { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected string CheckSel(AnagGruppiModel curItem)
{
string answ = "";
if (SelItem != null)
{
answ = curItem.Gruppo == SelItem.Gruppo ? "table-info" : "";
}
return answ;
}
protected async Task ClonaAssegnDip()
{
bool fatto = await GDataServ.Dipendenti2GrpClona(idxDipFrom, idxDipTo);
await ReloadData();
}
protected async Task CreateNew()
{
SelItem = new AnagGruppiModel()
{
Gruppo = "__Nuovo Gruppo",
DescrGruppo = $"Nuovo Gruppo - {DateTime.Now}",
CodExt = "",
ExportEnab = true
};
isEdit = true;
await InvokeAsync(StateHasChanged);
}
protected async void DoDelete(AnagGruppiModel selItem)
{
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Sicuro di voler eliminare il record?"))
return;
isLoading = true;
bool fatto = await GDataServ.AnagGruppiDelete(selItem);
await ReloadData();
await InvokeAsync(StateHasChanged);
}
protected void DoEdit(AnagGruppiModel? selItem)
{
isEdit = true;
SelItem = selItem;
}
protected void DoSelect(AnagGruppiModel? selItem)
{
isEdit = false;
SelItem = selItem;
}
protected async Task ForceReload(bool force)
{
SelItem = null;
await ReloadData();
}
protected override async Task OnInitializedAsync()
{
CurrSearch = "";
AppMServ.SearchVal = "";
AppMServ.EA_SearchUpdated += AppMServ_EA_SearchUpdated;
numRecord = await AppMServ.NumRowGridGet(gridKey);
}
protected override async Task OnParametersSetAsync()
{
await ReloadData();
}
protected async Task SetNumRec(int newNum)
{
numRecord = newNum;
currPage = 1;
await AppMServ.NumRowGridSet(gridKey, newNum);
await InvokeAsync(ReloadData);
}
protected async Task SetPage(int newNum)
{
currPage = newNum;
await InvokeAsync(ReloadData);
}
protected async Task SortRequested(Sorter.SortCallBack e)
{
sortField = e.ParamName;
sortAsc = e.IsAscending;
await ReloadData();
}
#endregion Protected Methods
#region Private Fields
private static Logger Log = LogManager.GetCurrentClassLogger();
private string gridKey = "GruppiMan";
private int idxDipFrom = 0;
private int idxDipTo = 0;
private bool isEdit = false;
private AnagGruppiModel? SelItem = null;
private bool sortAsc = true;
private string sortField = "";
#endregion Private Fields
#region Private Properties
private int currPage { get; set; } = 1;
private string CurrSearch { get; set; } = "";
private bool isLoading { get; set; } = false;
private List<DipendentiModel> ListDipendenti { get; set; } = new List<DipendentiModel>();
private List<AnagGruppiModel>? ListRecords { get; set; } = null;
private int numRecord { get; set; } = 10;
private List<AnagGruppiModel>? SearchRecords { get; set; } = null;
private int totalCount { get; set; } = 0;
#endregion Private Properties
#region Private Methods
private async void AppMServ_EA_SearchUpdated()
{
CurrSearch = AppMServ.SearchVal;
await ReloadData();
await InvokeAsync(StateHasChanged);
}
private void DoResetSelClona()
{
idxDipFrom = 0;
idxDipTo = 0;
}
private async Task ReloadData()
{
isLoading = true;
ListRecords = null;
ListDipendenti = await GDataServ.DipendentiGetAll();
try
{
SearchRecords = await GDataServ.AnagGruppiAll();
// verifico filtro per ricerca
if (!string.IsNullOrEmpty(CurrSearch))
{
SearchRecords = SearchRecords.Where(x => x.Gruppo.Contains(CurrSearch, StringComparison.InvariantCultureIgnoreCase) || x.DescrGruppo.Contains(CurrSearch, StringComparison.InvariantCultureIgnoreCase)).ToList();
}
}
catch (Exception ex)
{
Log.Error($"Eccezione in recupero dati{Environment.NewLine}{ex}");
}
totalCount = SearchRecords.Count;
SortTable();
isLoading = false;
}
private void SortTable()
{
if (SearchRecords != null)
{
// se ho ordinamento riordino...
if (!string.IsNullOrEmpty(sortField))
{
switch (sortField)
{
case "Descrizione":
if (sortAsc)
{
SearchRecords = SearchRecords.OrderBy(x => x.DescrGruppo).ToList();
}
else
{
SearchRecords = SearchRecords.OrderByDescending(x => x.DescrGruppo).ToList();
}
break;
case "CodGruppo":
if (sortAsc)
{
SearchRecords = SearchRecords.OrderBy(x => x.Gruppo).ToList();
}
else
{
SearchRecords = SearchRecords.OrderByDescending(x => x.Gruppo).ToList();
}
break;
case "CodExt":
if (sortAsc)
{
SearchRecords = SearchRecords.OrderBy(x => x.CodExt).ToList();
}
else
{
SearchRecords = SearchRecords.OrderByDescending(x => x.CodExt).ToList();
}
break;
case "Export":
if (sortAsc)
{
SearchRecords = SearchRecords.OrderBy(x => x.ExportEnab).ToList();
}
else
{
SearchRecords = SearchRecords.OrderByDescending(x => x.ExportEnab).ToList();
}
break;
default:
break;
}
}
// filtro x display
ListRecords = SearchRecords
.Skip(numRecord * (currPage - 1))
.Take(numRecord)
.ToList();
}
else
{
ListRecords = new List<AnagGruppiModel>();
}
}
#endregion Private Methods
}
}
@@ -0,0 +1,53 @@
<AuthorizeView>
<div class="d-flex justify-content-between w-100">
<div class="px-1">
<div class="d-flex">
<div class="px-1"><b>@userName</b></div>
<div class="px-1">
<button class="btn btn-sm btn-outline-dark" @onclick="() => DoReloadUtente()">
<i class="fas fa-user @cssActive" title="Attivazione Utente"></i>
</button>
</div>
<div class="px-1">
<button class="btn btn-sm btn-outline-dark" @onclick="() => DoVerifyActiv()">
<i class="fas fa-address-card @cssLicOk" title="Licenza assegnata"></i>
</button>
</div>
</div>
</div>
<div class="px-1 fs-3">
@if (!string.IsNullOrEmpty(PageIcon))
{
<i class="@PageIcon"></i>
}
@if (!string.IsNullOrEmpty(PageTitle))
{
<span class="px-2">@PageTitle</span>
}
</div>
<div class="px-1">
<div class="d-flex">
@if (showSearch)
{
<div class="px-1">
<div class="input-group" title="ricerca">
<span class="input-group-text"><i class="fas fa-search"></i></span>
<input type="text" class="form-control" @bind="@searchVal" accesskey="/" placeholder="[Alt-/] to select">
<button class="btn btn-outline-secondary" @onclick="resetSearch"><i class="fas fa-ban"></i></button>
</div>
</div>
}
<div class="px-1">
<select @bind="@UserLang" class="form-select" @bind:after="SaveLang">
@foreach (var item in ListLingue)
{
<option value="@item">@item</option>
}
</select>
</div>
</div>
</div>
</div>
</AuthorizeView>
@@ -0,0 +1,393 @@
using GPW.CORE.Data;
using GPW.CORE.Data.DbModels;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Components.Routing;
using Newtonsoft.Json;
using Microsoft.AspNetCore.Identity;
using GPW.CORE.Data.Services;
namespace GPW.CORE.ADM.Components.Compo
{
public partial class LoginDisplay : IDisposable
{
#region Public Methods
public void Dispose()
{
GDataServ.mPipeTimb.EA_NewMessage -= MPipeTimb_EA_NewMessage;
GDataServ.mPipeRich.EA_NewMessage -= MPipeRich_EA_NewMessage;
AppMServ.EA_HideSearch -= AppMServ_EA_HideSearch;
AppMServ.EA_HideSearch -= AppMServ_EA_ShowSearch;
AppMServ.EA_PageUpdated -= AppMServ_EA_PageUpdated;
}
#endregion Public Methods
#region Protected Properties
[Inject]
protected MessageService AppMServ { get; set; } = null!;
[Inject]
protected NavigationManager NavMan { get; set; } = null!;
[Inject]
protected AuthenticationStateProvider AuthenticationStateProvider { get; set; } = null!;
[Inject]
protected AppAuthService AuthServ { get; set; } = null!;
[Inject]
protected AppAuthService AuthService { get; set; } = null!;
[Inject]
protected IConfiguration config { get; set; } = null!;
protected string cssActive { get => AppMServ.IsActive ? "text-success" : "text-danger"; }
protected string cssLicOk { get => AppMServ.PayloadOk ? "text-success" : "text-danger"; }
[Inject]
protected GpwDataService GDataServ { get; set; } = null!;
[Inject]
protected LicenseService LicServ { get; set; } = null!;
protected List<string> ListLingue
{
get => AuthServ.Lingue;
}
protected string searchVal
{
get => AppMServ.SearchVal;
set => AppMServ.SearchVal = value;
}
protected string UserLang
{
get => AppMServ.UserLang;
set => AppMServ.UserLang = value;
}
#endregion Protected Properties
#region Protected Methods
/// <summary>
/// Verifica informazioni condivise applicazione
/// </summary>
/// <returns></returns>
protected async Task<bool> checkActivations()
{
bool allOk = false;
if (LicServ.ValidData)
{
// se non fosse tutto ok
if (!LicServ.HasActivData)
{
// chiamo refresh licenze da remoto
allOk = await LicServ.RefreshLicense();
}
}
await Task.Delay(1);
return allOk;
}
/// <summary>
/// Verifica informazioni condivise applicazione
/// </summary>
/// <returns></returns>
protected async Task<bool> checkSharedInfo()
{
bool allOk = false;
if (!LicServ.ValidData)
{
// salvo cod app da Conf...
LicServ.Applicazione = GDataServ.CodApp;
// effettuo lettura dati preliminari da AKV (eventualmente in cache...)
List<AnagKeyValueModel>? rawAkvList = await GDataServ.AKVList();
if (rawAkvList != null)
{
LicServ.AKVList = rawAkvList;
allOk = LicServ.InitAkv();
}
}
await Task.Delay(1);
return allOk;
}
/// <summary>
/// Verifica info specifiche utente
/// </summary>
/// <returns></returns>
protected async Task<bool> checkUserLicense()
{
bool answ = false;
// verifico utente attivo
answ = AppMServ.IsActive;
if (answ)
{
var rawActList = LicServ.ActivList;
// recupero hash utente
string hashImpiego = AppMServ.HashDip;
// confronto con elenco attivazioni dello shared service...
var foundRec = rawActList.Where(x => x.CodImpiego == hashImpiego);
answ = foundRec.Count() > 0;
// salvo status payloadOk
AppMServ.PayloadOk = answ;
}
await Task.Delay(1);
return answ;
}
protected async Task DoReloadUtente()
{
AppMServ.RigaDip = null;
await Task.Delay(1);
await LoadUtente();
// recupero dati conf lingua...
await ReloadLang();
// verifico attivazione dipendente...
await checkUserLicense();
}
protected async Task DoVerifyActiv()
{
AppMServ.PayloadOk = false;
// svuoto oggetto activList...
LicServ.ActivList = new List<LiManObj.AttivazioneDTO>();
await LicServ.resetActivList();
await Task.Delay(50);
await VerifyActiv();
}
protected async Task LoadUtente()
{
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
var user = authState.User;
// verifico se ho utente loggato...
if (user.Identity != null && user.Identity.IsAuthenticated)
{
userName = $"{user.Identity.Name}";
// cerco su DB
DipendentiModel? rigaDip = ListaDip.Where(x => $"{x.Dominio.Trim()}\\{x.Utente.Trim()}".ToLower() == userName.Trim().ToLower()).FirstOrDefault();
if (rigaDip != null)
{
// salvo riga info dipendente
AppMServ.RigaDip = rigaDip;
userName = $"{rigaDip.Cognome} {rigaDip.Nome}";
idxDipendente = rigaDip.IdxDipendente;
// leggo e salvo in MsgService il menù utente...
var listMenu = await AuthService.MenuUtente(rigaDip.Utente, UserLang);
AppMServ.ListMenu = listMenu;
}
}
else
{
userName = "N.A.";
}
}
protected override async Task OnInitializedAsync()
{
// aggiungo gestione notifica messaggi timbrature...
GDataServ.mPipeTimb.EA_NewMessage += MPipeTimb_EA_NewMessage;
GDataServ.mPipeRich.EA_NewMessage += MPipeRich_EA_NewMessage;
AppMServ.EA_HideSearch += AppMServ_EA_HideSearch;
AppMServ.EA_ShowSearch += AppMServ_EA_ShowSearch;
AppMServ.EA_PageUpdated += AppMServ_EA_PageUpdated;
// leggo lingue...
UserLang = await AppMServ.UserLangGet();
// leggo lista dip
ListaDip = await GDataServ.DipendentiGetAll();
numTot = ListaDip.Count(x => x.Attivo == true);
//effettuo eventuale recupero dati dipendente
if (AppMServ.RigaDip == null)
{
await LoadUtente();
}
// verifica attivazione
await VerifyActiv();
// verifica rpesenza personale
await VerifPresenze(false);
}
protected void resetSearch()
{
searchVal = "";
}
protected async Task VerifyActiv()
{
// preliminarmente verifica shared info
await checkSharedInfo();
// refresh attivazioni se necessario
await checkActivations();
// verifico e salvo dati attivazione dipendente...
await checkUserLicense();
// verifica admin
checkAdmin();
}
#endregion Protected Methods
#region Private Fields
private int idxDipendente = 0;
private bool isAdmin = false;
private List<DipendentiModel> ListaDip = new List<DipendentiModel>();
private List<StatsDayPresModel> ListaPres = new List<StatsDayPresModel>();
private List<string> ListIdxAdmin = new List<string>();
private int numPres = 0;
private int numTot = 0;
private string PageIcon = "";
private string PageTitle = "";
private bool showSearch = false;
private string userName = "";
#endregion Private Fields
#region Private Properties
private string lblDisplay { get; set; } = "";
[Inject]
private NavigationManager NavManager { get; set; } = null!;
#endregion Private Properties
#region Private Methods
private void AppMServ_EA_HideSearch()
{
showSearch = false;
}
private void AppMServ_EA_PageUpdated()
{
PageTitle = AppMServ.PageName;
PageIcon = AppMServ.PageIcon;
InvokeAsync(StateHasChanged);
}
private void AppMServ_EA_ShowSearch()
{
showSearch = true;
}
private void checkAdmin()
{
// leggo elenco admin
string rawData = config.GetValue<string>("ServerConf:AdmList") ?? "";
if (!string.IsNullOrEmpty(rawData))
{
ListIdxAdmin = rawData.Split(',').ToList();
}
isAdmin = ListIdxAdmin.Contains($"{idxDipendente}");
}
private async void MPipeRich_EA_NewMessage(object? sender, EventArgs e)
{
await processMessage(e);
}
private async void MPipeTimb_EA_NewMessage(object? sender, EventArgs e)
{
await processMessage(e);
}
private async Task processMessage(EventArgs e)
{
PubSubEventArgs currArgs = (PubSubEventArgs)e;
// conversione on-the-fly List<string> --> allarmi
if (!string.IsNullOrEmpty(currArgs.newMessage))
{
try
{
TimbratureModel? timbData = JsonConvert.DeserializeObject<TimbratureModel>(currArgs.newMessage);
if (timbData != null)
{
// solo se admin
if (isAdmin)
{
updateDisplay(timbData);
await InvokeAsync(StateHasChanged);
await ResetMessage(6);
}
}
}
catch
{ }
}
}
private async Task ReloadLang()
{
UserLang = await AppMServ.UserLangGet();
}
/// <summary>
/// Chiama reset messaggio dopo un periodo di sec richiesto...
/// </summary>
/// <returns></returns>
private async Task ResetMessage(int numSec)
{
// chiudo visualizzazione stato update
await Task.Delay(numSec * 1000);
lblDisplay = "";
await VerifPresenze(true);
await InvokeAsync(StateHasChanged);
}
private async void SaveLang()
{
await AppMServ.UserLangSet(UserLang);
// vado a pagina reload...
NavMan.NavigateTo("ForceReset", true);
}
private void updateDisplay(TimbratureModel timbData)
{
string tipo = timbData.Entrata ?? true ? "IN" : "OUT";
string dipData = $"Dip: {timbData.IdxDipendente}";
//cerco dip...
var currDip = ListaDip.Find(x => x.IdxDipendente == timbData.IdxDipendente);
if (currDip != null)
{
dipData = $"{currDip.Cognome} {currDip.Nome} ({timbData.IdxDipendente})";
}
lblDisplay = $"{tipo} | {dipData} | {timbData.DataOra:HH:mm:ss}";
}
private async Task VerifPresenze(bool resetCache)
{
if (resetCache)
{
await GDataServ.FlushRedisCache();
}
ListaPres = await GDataServ.PresenzeDay(DateTime.Now);
numPres = ListaPres.Sum(x => x.IsPresent);
}
#endregion Private Methods
}
}
@@ -0,0 +1,40 @@
<div class="card shadow">
<div class="card-header">
<div class="d-flex justify-content-between">
<div class="px-0 d-flex">
<div class="px-0">
<h3>@Traduci("tagMensili")</h3>
</div>
<div class="px-2">
<button class="btn btn-success" @onclick=Recalc tooltip="Add New"><i class="fa-solid fa-plus"></i> @Traduci("Ricalcola")</button>
</div>
</div>
<div class="px-0">
<div class="d-flex align-middle">
<div class="px-1 py-2">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" @bind=@ShowInatt @bind:after=ForceReload>
<label class="form-check-label">Mostra Inattivi</label>
</div>
</div>
<div class="px-1 py-1">
<select @bind="@IdxDipSel" class="form-select form-select-sm" @bind:after=ForceReload>
<option value="0">--- Selezionare ---</option>
@foreach (var item in ListDipendenti)
{
<option value="@item.IdxDipendente">@($"{item.Cognome} {item.Nome}")</option>
}
</select>
</div>
<div class="px-0">
<PeriodoSel CurrPeriodo="@CurrPeriodo" E_PeriodoSel="@SavePeriodo"></PeriodoSel>
</div>
</div>
</div>
</div>
</div>
<div class="card-body p-1 small">
<p>elenco da stored</p>
</div>
</div>
@@ -0,0 +1,117 @@
using EgwCoreLib.Utils;
using GPW.CORE.Data.DbModels;
using GPW.CORE.Data.Services;
using Microsoft.AspNetCore.Components;
namespace GPW.CORE.ADM.Components.Compo
{
public partial class MonthTagMan
{
#region Protected Properties
[Inject]
protected MessageService AppMServ { get; set; } = null!;
[Inject]
protected AppAuthService AuthServ { get; set; } = null!;
[Inject]
protected GpwDataService GDataServ { get; set; } = null!;
protected int IdxDipSel { get; set; } = 0;
#endregion Protected Properties
#region Protected Methods
protected async Task ForceReload()
{
currPage = 1;
SelRecord = null;
await ReloadData();
}
protected override async Task OnInitializedAsync()
{
CurrPeriodo.Fine = DateTime.Today.AddDays(1);
}
protected async void Recalc()
{
await Task.Delay(200);
}
protected string Traduci(string lemma)
{
return AuthServ.Traduci(lemma, AppMServ.UserLang);
}
#endregion Protected Methods
#region Private Properties
private int currPage { get; set; } = 1;
private DtUtils.Periodo CurrPeriodo { get; set; } = new DtUtils.Periodo(DtUtils.PeriodSet.ThisMonth);
private bool isLoading { get; set; } = false;
private List<DipendentiModel> ListDipendenti { get; set; } = new List<DipendentiModel>();
private List<MonthTagModel>? ListRecords { get; set; } = null;
private int numRecord { get; set; } = 10;
private MonthTagModel? SelRecord { get; set; } = null;
private bool ShowInatt { get; set; } = false;
private int totalCount { get; set; } = 0;
#endregion Private Properties
#region Private Methods
private async Task ReloadData()
{
isLoading = true;
ListRecords = null;
var rawList = await GDataServ.DipendentiGetAll();
if (ShowInatt)
{
ListDipendenti = rawList;
}
else
{
ListDipendenti = rawList.Where(x => (x.Attivo ?? false)).ToList();
}
#if false
try
{
SearchRecords = await GDataServ.TeRaExplGetFilt(IdxDipSel, CurrPeriodo.Inizio, CurrPeriodo.Fine, ShowInatt, ShowWE, MaxErrMin, MaxErrPlus);
// verifico filtro per IdxDip
if (IdxDipSel > 0)
{
SearchRecords = SearchRecords.Where(x => x.IdxDipendente == IdxDipSel).ToList();
}
}
catch (Exception ex)
{
Log.Error($"Eccezione in recupero dati{Environment.NewLine}{ex}");
}
totalCount = SearchRecords.Count;
SortTable();
isLoading = false;
// tolgo eventuale send data...
isSendingData = false;
#endif
await Task.Delay(1);
}
private async Task SavePeriodo(DtUtils.Periodo newPeiodo)
{
CurrPeriodo = newPeiodo;
await ReloadData();
}
#endregion Private Methods
}
}
@@ -0,0 +1,143 @@
<div class="row g-1">
<div class="col-2">
<div class="form-floating">
<input type="text" class="form-control" @bind="@CurrRecord.codOrario">
<label class="small">Codice</label>
</div>
</div>
<div class="col-6">
<div class="row mx-1">
<div class="col px-0">
<div class="form-floating">
<input type="number" class="form-control" @bind="@CurrRecord.oreLun">
<label class="small">Lun</label>
</div>
</div>
<div class="col px-0">
<div class="form-floating">
<input type="number" class="form-control" @bind="@CurrRecord.oreMar">
<label class="small">Mar</label>
</div>
</div>
<div class="col px-0">
<div class="form-floating">
<input type="number" class="form-control" @bind="@CurrRecord.oreMer">
<label class="small">Mer</label>
</div>
</div>
<div class="col px-0">
<div class="form-floating">
<input type="number" class="form-control" @bind="@CurrRecord.oreGio">
<label class="small">Gio</label>
</div>
</div>
<div class="col px-0">
<div class="form-floating">
<input type="number" class="form-control" @bind="@CurrRecord.oreVen">
<label class="small">Ven</label>
</div>
</div>
<div class="col px-0">
<div class="form-floating">
<input type="number" class="form-control" @bind="@CurrRecord.oreSab">
<label class="small">Sab</label>
</div>
</div>
<div class="col px-0">
<div class="form-floating">
<input type="number" class="form-control" @bind="@CurrRecord.oreDom">
<label class="small">Dom</label>
</div>
</div>
</div>
</div>
<div class="col-4">
<div class="row mx-1">
<div class="col px-0">
<div class="form-floating">
<div type="number" class="form-control" disabled>@CurrRecord.oreOrdSett</div>
<label class="small">Tot Ord</label>
</div>
</div>
<div class="col px-0">
<div class="form-floating">
<input type="number" class="form-control" @bind="@CurrRecord.oreStraordAss">
<label class="small">Straord.Ass.</label>
</div>
</div>
<div class="col px-0">
<div class="form-floating">
<div class="form-control">
<input class="form-check-input" type="checkbox" @bind="@CurrRecord.autoCompOreOrd">
</div>
<label class="small">AutoComp.</label>
</div>
</div>
</div>
</div>
</div>
<div class="row g-1">
<div class="col-4">
<div class="row mx-1">
<div class="col px-0">
<div class="form-floating">
<input type="datetime" class="form-control" @bind="@CurrRecord.oraInizio1">
<label class="small">Ora Inizio 1</label>
</div>
</div>
<div class="col px-0">
<div class="form-floating">
<input type="datetime" class="form-control" @bind="@CurrRecord.oraFine1">
<label class="small">Ora Fine 1</label>
</div>
</div>
</div>
</div>
<div class="col-4">
<div class="row mx-1">
<div class="col px-0">
<div class="form-floating">
<input type="datetime" class="form-control" @bind="@CurrRecord.oraInizio2">
<label class="small">Ora Inizio 2</label>
</div>
</div>
<div class="col px-0">
<div class="form-floating">
<input type="datetime" class="form-control" @bind="@CurrRecord.oraFine2">
<label class="small">Ora Fine 2</label>
</div>
</div>
</div>
</div>
<div class="col-4">
<div class="row mx-1">
<div class="col px-0">
<div class="form-floating">
<input type="datetime" class="form-control" @bind="@CurrRecord.oraInizio3">
<label class="small">Ora Inizio 3</label>
</div>
</div>
<div class="col px-0">
<div class="form-floating">
<input type="datetime" class="form-control" @bind="@CurrRecord.oraFine3">
<label class="small">Ora Fine 3</label>
</div>
</div>
</div>
</div>
</div>
<div class="row g-1">
<div class="col-md-10">
<div class="form-floating">
<textarea class="form-control" @bind="@CurrRecord.descOrario" rows="2" style="height: 6rem;"></textarea>
<label class="small">Descrizione</label>
</div>
</div>
<div class="col-md-2 pt-2 d-flex align-items-center">
<div class="w-100">
<button class="btn btn-success my-1 w-100" @onclick="() => DoSave()"><i class="fas fa-floppy-disk"></i> Save</button>
<button class="btn btn-warning my-1 w-100" @onclick="() => DoCancel()"><i class="fas fa-ban"></i> Cancel</button>
</div>
</div>
</div>
@@ -0,0 +1,61 @@
using GPW.CORE.Data.DbModels;
using GPW.CORE.Data.DTO;
using GPW.CORE.Data.Services;
using Microsoft.AspNetCore.Components;
namespace GPW.CORE.ADM.Components.Compo
{
public partial class OrarioEdit
{
#region Public Properties
[Parameter]
public AnagOrariModel? CurrRecord { get; set; } = null;
[Parameter]
public EventCallback<bool> EC_update { get; set; }
[Parameter]
public List<TagFasiDTO> ListTagFasi { get; set; } = null!;
#endregion Public Properties
#region Protected Properties
[Inject]
protected GpwDataService GDataServ { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected async Task DoCancel()
{
await EC_update.InvokeAsync(true);
}
protected async Task DoSave()
{
bool fatto = false;
await Task.Delay(1);
if (CurrRecord != null)
{
fatto = await GDataServ.AnagOrarioUpsert(CurrRecord, codOrarioOrig);
}
await EC_update.InvokeAsync(fatto);
}
protected override void OnParametersSet()
{
codOrarioOrig = CurrRecord.codOrario;
}
#endregion Protected Methods
#region Private Fields
private string codOrarioOrig = "";
#endregion Private Fields
}
}
@@ -0,0 +1,126 @@
@if (RecordEdit != null)
{
<div class="modal fade show" tabindex="-1" style="display:block; background-color: rgba(10,10,10,.6);" aria-modal="true" role="dialog" data-keyboard="true">
<div class="modal-dialog modal-xl">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Modifica Orario <b>@RecordEdit.codOrario</b></h4>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" @onclick="()=> ForceReload(true)"></button>
</div>
<div class="modal-body p-1">
<OrarioEdit CurrRecord=@RecordEdit EC_update=ForceReload></OrarioEdit>
</div>
</div>
</div>
</div>
}
<div class="card shadow">
<div class="card-header">
<div class="d-flex justify-content-between">
<div class="px-0">
<h3>Gestione Orario</h3>
</div>
<div class="px-0">
<button class="btn btn-success" @onclick="AddNew"><i class="fas fa-plus"></i> Add New</button>
</div>
</div>
</div>
<div class="card-body p-1">
@if (ListRecords == null || isLoading)
{
<EgwCoreLib.Razor.LoadingData></EgwCoreLib.Razor.LoadingData>
}
else if (totalCount == 0)
{
<div class="alert alert-info">Nessun record trovato</div>
}
else
{
<table class="table table-striped table-sm text-start">
<thead>
<tr class="">
<th>
<button class="btn btn-primary btn-sm" @onclick="() => ForceReload(true)"><i class="fa-solid fa-rotate"></i></button>
</th>
<th>Cod <Sorter ParamName="Cod" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
<th>Descrizione <Sorter ParamName="Descrizione" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
<th>Lun</th>
<th>Mar</th>
<th>Mer</th>
<th>Gio</th>
<th>Ven</th>
<th>Sab</th>
<th>Dom</th>
<th>Ordin <Sorter ParamName="Ordin" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
<th>Straord <Sorter ParamName="Straord" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
<th>Comp <Sorter ParamName=">Comp" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
<th>Inizio 1</th>
<th>Fine 1</th>
<th>Inizio 2</th>
<th>Fine 2</th>
<th>Inizio 3</th>
<th>Fine 3</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in ListRecords)
{
<tr class="align-middle @CheckSel(item)">
<td>
@if (RecordEdit == null)
{
<button class="btn btn-primary btn-sm" @onclick="() => DoEdit(item)"><i class="fa-solid fa-edit"></i></button>
}
else
{
<button class="btn btn-secondary btn-sm" disabled><i class="fa-solid fa-edit"></i></button>
}
</td>
<td>
<div class="fw-bold fs-5">
@item.codOrario
</div>
</td>
<td>
@item.descOrario
</td>
<td>@item.oreLun</td>
<td>@item.oreMar</td>
<td>@item.oreMer</td>
<td>@item.oreGio</td>
<td>@item.oreVen</td>
<td>@item.oreSab</td>
<td>@item.oreDom</td>
<td>@item.oreOrdSett</td>
<td>@item.oreStraordAss</td>
<td>
<input class="form-check-input" type="checkbox" disabled @bind="@item.autoCompOreOrd">
</td>
<td>@item.oraInizio1</td>
<td>@item.oraFine1</td>
<td>@item.oraInizio2</td>
<td>@item.oraFine2</td>
<td>@item.oraInizio3</td>
<td>@item.oraFine3</td>
<td>
@if (item.DipendentiNav == null || item.DipendentiNav.Count == 0)
{
<button class="btn btn-danger btn-sm" @onclick="() => DoDelete(item)"><i class="fa-solid fa-trash"></i></button>
}
else
{
<button class="btn btn-secondary btn-sm" disabled><i class="fa-solid fa-trash"></i></button>
}
</td>
</tr>
}
</tbody>
</table>
}
</div>
<div class="card-footer">
<EgwCoreLib.Razor.DataPager PageSize="@numRecord" currPage="@currPage" numRecordChanged="SetNumRec" numPageChanged="SetPage" totalCount="@totalCount" showLoading="@isLoading"></EgwCoreLib.Razor.DataPager>
</div>
</div>
@@ -0,0 +1,256 @@
using EgwCoreLib.Razor;
using GPW.CORE.Data.DbModels;
using GPW.CORE.Data.Services;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using NLog;
using static EgwCoreLib.Razor.Toggler;
namespace GPW.CORE.ADM.Components.Compo
{
public partial class OrarioMan : IDisposable
{
#region Public Methods
public void Dispose()
{
AppMServ.EA_SearchUpdated -= AppMServ_EA_SearchUpdated;
}
#endregion Public Methods
#region Protected Properties
[Inject]
protected MessageService AppMServ { get; set; } = null!;
[Inject]
protected GpwDataService GDataServ { get; set; } = null!;
[Inject]
protected IJSRuntime JSRuntime { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected string CheckSel(AnagOrariModel curItem)
{
string answ = "";
if (RecordEdit != null)
{
answ = curItem.codOrario == RecordEdit.codOrario ? "table-info" : "";
}
return answ;
}
protected async void DoDelete(AnagOrariModel selItem)
{
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Sicuro di voler eliminare il record?"))
return;
isLoading = true;
bool fatto = await GDataServ.AnagOrarioDelete(selItem);
await ReloadData();
await InvokeAsync(StateHasChanged);
}
private void AddNew()
{
RecordEdit = new AnagOrariModel()
{
codOrario = "_000h",
descOrario = "Nuovo Orario",
oreLun = 8,
oreMar = 8,
oreMer = 8,
oreGio = 8,
oreVen = 8,
autoCompOreOrd = true
};
}
protected void DoEdit(AnagOrariModel? selItem)
{
RecordEdit = selItem;
}
protected async Task ForceReload(bool force)
{
RecordEdit = null;
await ReloadData();
}
protected override async Task OnInitializedAsync()
{
CurrSearch = "";
AppMServ.SearchVal = "";
AppMServ.EA_SearchUpdated += AppMServ_EA_SearchUpdated;
numRecord = await AppMServ.NumRowGridGet(gridKey);
}
protected override async Task OnParametersSetAsync()
{
await ReloadData();
}
protected async Task SetNumRec(int newNum)
{
numRecord = newNum;
currPage = 1;
await AppMServ.NumRowGridSet(gridKey, newNum);
await InvokeAsync(ReloadData);
}
protected async Task SetPage(int newNum)
{
currPage = newNum;
await InvokeAsync(ReloadData);
}
protected async Task SortRequested(Sorter.SortCallBack e)
{
sortField = e.ParamName;
sortAsc = e.IsAscending;
await ReloadData();
}
#endregion Protected Methods
#region Private Fields
private static Logger Log = LogManager.GetCurrentClassLogger();
private string gridKey = "OrariMan";
private AnagOrariModel? RecordEdit = null;
private bool sortAsc = true;
private string sortField = "";
#endregion Private Fields
#region Private Properties
private int currPage { get; set; } = 1;
private string CurrSearch { get; set; } = "";
private bool isLoading { get; set; } = false;
private List<AnagOrariModel>? ListRecords { get; set; } = null;
private int numRecord { get; set; } = 10;
private List<AnagOrariModel>? SearchRecords { get; set; } = null;
private int totalCount { get; set; } = 0;
#endregion Private Properties
#region Private Methods
private async void AppMServ_EA_SearchUpdated()
{
CurrSearch = AppMServ.SearchVal;
await ReloadData();
await InvokeAsync(StateHasChanged);
}
private async Task ReloadData()
{
isLoading = true;
ListRecords = null;
try
{
SearchRecords = await GDataServ.AnagOrarioAll();
// verifico filtro per ricerca
if (!string.IsNullOrEmpty(CurrSearch))
{
SearchRecords = SearchRecords.Where(x => x.descOrario.Contains(CurrSearch, StringComparison.InvariantCultureIgnoreCase)).ToList();
}
}
catch (Exception ex)
{
Log.Error($"Eccezione in recupero dati{Environment.NewLine}{ex}");
}
totalCount = SearchRecords.Count;
SortTable();
isLoading = false;
}
private void SortTable()
{
if (SearchRecords != null)
{
// se ho ordinamento riordino...
if (!string.IsNullOrEmpty(sortField))
{
switch (sortField)
{
case "Cod":
if (sortAsc)
{
SearchRecords = SearchRecords.OrderBy(x => x.codOrario).ToList();
}
else
{
SearchRecords = SearchRecords.OrderByDescending(x => x.codOrario).ToList();
}
break;
case "Descrizione":
if (sortAsc)
{
SearchRecords = SearchRecords.OrderBy(x => x.descOrario).ToList();
}
else
{
SearchRecords = SearchRecords.OrderByDescending(x => x.descOrario).ToList();
}
break;
case "Ordin":
if (sortAsc)
{
SearchRecords = SearchRecords.OrderBy(x => x.oreOrdSett).ToList();
}
else
{
SearchRecords = SearchRecords.OrderByDescending(x => x.oreOrdSett).ToList();
}
break;
case "Straord":
if (sortAsc)
{
SearchRecords = SearchRecords.OrderBy(x => x.oreStraordAss).ToList();
}
else
{
SearchRecords = SearchRecords.OrderByDescending(x => x.oreStraordAss).ToList();
}
break;
case "Comp":
if (sortAsc)
{
SearchRecords = SearchRecords.OrderBy(x => x.autoCompOreOrd).ToList();
}
else
{
SearchRecords = SearchRecords.OrderByDescending(x => x.autoCompOreOrd).ToList();
}
break;
default:
break;
}
}
// filtro x display
ListRecords = SearchRecords
.Skip(numRecord * (currPage - 1))
.Take(numRecord)
.ToList();
}
else
{
ListRecords = new List<AnagOrariModel>();
}
}
#endregion Private Methods
}
}
@@ -0,0 +1,90 @@
<div class="row g-1">
<ul class="list-group">
<li class="list-group-item">
<div class="d-flex justify-content-between">
<div class="px-0">
Budget
<div><b>@($"{CurrRecord.budgetTime:N0}")</b> h</div>
</div>
<div class="px-0">
<label class="small">Attivo</label>
<div class="form-check form-switch">
<input type="checkbox" class="form-check-input" @bind="@CurrRecord.Attivo" @bind:after=DoUpdate>
</div>
</div>
</div>
</li>
<li class="list-group-item">
<div class="d-flex justify-content-between">
<div class="px-0">
Erogate
<div><b>@($"{CurrRecord.totOre:N2}")</b> h</div>
</div>
<div class="px-0">
<label class="small">% budget</label>
<div><b>@($"{CurrRecord.totOre / CurrRecord.budgetTime:P1}")</b></div>
</div>
</div>
</li>
<li class="list-group-item">
<div class="d-flex justify-content-between">
<div class="px-0">
Mese Corr.
<div><b>@($"{CurrRecord.totOreLast30:N2}")</b> h</div>
</div>
<div class="px-0">
<label class="small">% budget</label>
<div><b>@($"{CurrRecord.totOreLast30 / CurrRecord.budgetTime:P1}")</b></div>
</div>
</div>
</li>
<li class="list-group-item">
<div class="d-flex justify-content-between">
<div class="px-0">
Mese Prec.
<div><b>@($"{CurrRecord.totOrePrevMont:N2}")</b> h</div>
</div>
<div class="px-0">
<label class="small">% budget</label>
<div><b>@($"{CurrRecord.totOrePrevMont / CurrRecord.budgetTime:P1}")</b></div>
</div>
</div>
</li>
<li class="list-group-item">
<div class="d-flex justify-content-between">
<div class="px-0">
Starred
</div>
<div class="px-0">
<div class="form-check form-switch">
<input type="checkbox" class="form-check-input" @bind="@CurrRecord.Starred" @bind:after=DoUpdate>
</div>
</div>
</div>
</li>
<li class="list-group-item bg-info bg-opacity-25 bg-gradient">
<div class="d-flex justify-content-between">
<h5>Duplica Progetto Corrente</h5>
</div>
<div class="d-flex justify-content-between">
<div class="px-0">
Nome
</div>
<div class="px-0">
<input type="text" class="form-control text-end" @bind="@NewProjName"></input>
</div>
</div>
<div class="d-flex justify-content-between">
<div class="px-0">
Sost. anno in fasi
</div>
<div class="px-0">
<div class="form-check form-switch">
<input type="checkbox" class="form-check-input" @bind="@DoYearSubst">
</div>
</div>
</div>
<button class="btn btn-primary w-100" @onclick=DoClone><i class="fa-regular fa-clone"></i> Duplica</button>
</li>
</ul>
</div>
@@ -0,0 +1,72 @@
using GPW.CORE.Data.DbModels;
using GPW.CORE.Data.Services;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
namespace GPW.CORE.ADM.Components.Compo
{
public partial class ProgettiDetail
{
#region Public Properties
[Parameter]
public CalcOreProgettiModel? CurrRecord { get; set; } = null;
[Parameter]
public EventCallback<bool> EC_update { get; set; }
#endregion Public Properties
#region Protected Properties
[Inject]
protected GpwDataService GDataServ { get; set; } = null!;
[Inject]
protected IJSRuntime JSRuntime { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected async Task DoUpdate()
{
await GDataServ.AnagProjUpdStatus(CurrRecord.IdxProgetto, CurrRecord.Attivo ?? true, CurrRecord.Starred ?? false);
}
protected override void OnParametersSet()
{
NewProjName = CurrRecord.NomeProj;
DoYearSubst = true;
}
protected async Task DoClone()
{
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Sicuro di voler procedere con la clonazione del progetto(+fasi) selezionato?"))
return;
bool fatto = false;
await Task.Delay(1);
if (CurrRecord != null)
{
fatto = await GDataServ.AnagProjDoClone(CurrRecord.IdxProgetto, NewProjName, DoYearSubst);
// se fatto ricalcolo...
if (fatto)
{
await GDataServ.AnagProjForceUpdate();
}
}
await EC_update.InvokeAsync(fatto);
}
private string NewProjName = "";
private bool DoYearSubst = true;
protected async Task DoCancel()
{
await EC_update.InvokeAsync(true);
}
#endregion Protected Methods
}
}
@@ -0,0 +1,71 @@
<div class="row g-1">
<div class="col-md-3">
<div class="form-floating">
<div class="form-control">
<select @bind="@CurrRecord.Gruppo" class="form-select form-select-sm" title="Gruppo">
<option value="">--- Selezionare ---</option>
@foreach (var item in ListGruppi)
{
<option value="@item.Gruppo">@item.DescrGruppo</option>
}
</select>
</div>
<label class="small">Gruppo</label>
</div>
</div>
<div class="col-md-3">
<div class="form-floating">
<div class="form-control">
<select @bind="@CurrRecord.IdxCliente" class="form-select form-select-sm" title="Cliente">
<option value="0">--- Selezionare ---</option>
@foreach (var item in ListClienti)
{
<option value="@item.IdxCliente">@item.RagSociale</option>
}
</select>
</div>
<label class="small">Rag.Sociale</label>
</div>
</div>
<div class="col-md-4">
<div class="form-floating">
<input type="text" class="form-control" @bind="@CurrRecord.NomeProj">
<label class="small">Nome</label>
</div>
</div>
<div class="col-md-1">
<div class="form-floating">
<div class="form-control">
<div class="form-check form-switch">
<input type="checkbox" class="form-check-input" @bind="@CurrRecord.Attivo">
</div>
</div>
<label class="small">Att.</label>
</div>
</div>
<div class="col-md-1">
<div class="form-floating">
<span class="form-control">
<span class="form-check form-switch">
<input type="checkbox" class="form-check-input" @bind="@CurrRecord.Starred">
</span>
</span>
<label class="small">Starred</label>
</div>
</div>
</div>
<div class="row g-1">
<div class="col-md-10">
<div class="form-floating">
<textarea class="form-control" @bind="@CurrRecord.DescrProj" rows="2" style="height: 9rem;"></textarea>
<label class="small">Descr</label>
</div>
</div>
<div class="col-md-2 pt-2 d-flex align-items-center">
<div class="w-100">
<button class="btn btn-success my-1 w-100" @onclick="() => DoSave()"><i class="fas fa-floppy-disk"></i> Save</button>
<button class="btn btn-warning my-1 w-100" @onclick="() => DoCancel()"><i class="fas fa-ban"></i> Cancel</button>
</div>
</div>
</div>
@@ -0,0 +1,57 @@
using GPW.CORE.Data.DbModels;
using GPW.CORE.Data.Services;
using Microsoft.AspNetCore.Components;
namespace GPW.CORE.ADM.Components.Compo
{
public partial class ProgettiEdit
{
#region Public Properties
[Parameter]
public AnagProgettiModel? CurrRecord { get; set; } = null;
[Parameter]
public EventCallback<bool> EC_update { get; set; }
[Parameter]
public List<AnagClientiModel> ListClienti { get; set; } = null!;
[Parameter]
public List<AnagGruppiModel> ListGruppi { get; set; } = null!;
#endregion Public Properties
#region Protected Properties
[Inject]
protected GpwDataService GDataServ { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected async Task DoCancel()
{
await EC_update.InvokeAsync(true);
}
protected async Task DoSave()
{
bool fatto = false;
await Task.Delay(1);
if (CurrRecord != null)
{
fatto = await GDataServ.AnagProjUpsert(CurrRecord);
// se fatto ricalcolo...
if (fatto)
{
await GDataServ.AnagProjForceUpdate();
}
}
await EC_update.InvokeAsync(fatto);
}
#endregion Protected Methods
}
}
@@ -0,0 +1,263 @@
@if (!ShowFasi && (RecordEdit != null || RecordSel != null))
{
<div class="modal fade show" tabindex="-1" style="display:block; background-color: rgba(10,10,10,.6);" aria-modal="true" role="dialog" data-keyboard="true">
<div class="modal-dialog @modalSize">
<div class="modal-content">
<div class="modal-header">
@if (FullEdit)
{
<h4 class="modal-title">Modifica Progetto <b>@RecordEdit.IdxProgetto</b></h4>
}
else
{
<h4 class="modal-title">Resoconto Progetto <b>@RecordSel.IdxProgetto</b></h4>
}
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" @onclick=ForceReload></button>
</div>
<div class="modal-body p-1 small">
@if (FullEdit)
{
<ProgettiEdit CurrRecord=@RecordEdit EC_update="ForceReload" ListGruppi=@ListGruppi ListClienti=@ListClienti></ProgettiEdit>
}
else
{
<ProgettiDetail CurrRecord=@RecordSel EC_update="ForceReload"></ProgettiDetail>
}
</div>
</div>
</div>
</div>
}
<div class="card shadow">
<div class="card-header">
<div class="d-flex justify-content-between">
<div class="px-0">
<div class="d-flex">
<div class="p-0">
<h3>@Traduci("ManProg")</h3>
</div>
<div class="px-2">
<button class="btn btn-warning" @onclick=DoRecalc><i class="fa-solid fa-arrows-rotate"></i> Force Recalc</button>
</div>
<div class="px-0">
<button class="btn btn-success" @onclick=CreateNew tooltip="Add New"><i class="fa-solid fa-plus"></i> Add New</button>
</div>
</div>
</div>
<div class="px-2 bg-secondary bg-opacity-25 bg-gradient rounded d-flex align-items-center">
<div class="d-flex align-items-center">
<div class="px-1">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" @bind=@ShowPrjArc @bind:after=@ForceReload>
<label class="form-check-label">Mostra Archiviati</label>
</div>
</div>
<div class="px-1">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" @bind=@ShowPrjZH @bind:after=@ForceReload>
<label class="form-check-label">Mostra Vuoti</label>
</div>
</div>
<div class="px-1">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" @bind=@ShowPrjStr @bind:after=@ForceReload>
<label class="form-check-label">Mostra SOLO Starred</label>
</div>
</div>
<div class="px-1">
<div class="d-flex border rounded px-2">
<div class="form-check py-1">
<input class="form-check-input" type="checkbox" @bind="@ShowGruppo" @bind:after=@FixFilt>
<label class="form-check-label text-nowrap">@SelGrpText</label>
</div>
@if (ShowGruppo)
{
<div class="input-group input-group-sm" title="Gruppo">
<span class="input-group-text">
<i class="far fa-object-group"></i>
</span>
<select @bind="@Gruppo" class="form-select form-select-sm" title="Gruppo" style="width:10rem;" @bind:after=@ForceReload>
<option value="">--- Selezionare ---</option>
@foreach (var item in ListGruppi)
{
<option value="@item.Gruppo">@item.DescrGruppo</option>
}
</select>
</div>
}
</div>
</div>
<div class="px-0">
<div class="d-flex border rounded px-2">
<div class="form-check py-1">
<input class="form-check-input" type="checkbox" @bind="@ShowCli" @bind:after=@FixFilt>
<label class="form-check-label text-nowrap">@SelCliText</label>
</div>
@if (ShowCli)
{
<div class="input-group input-group-sm" title="Cliente">
<span class="input-group-text">
<i class="far fa-object-group"></i>
</span>
<select @bind="@IdxCliente" class="form-select form-select-sm" title="Cliente" style="width:10rem;" @bind:after=@ForceReload>
<option value="0">--- Selezionare ---</option>
@foreach (var item in ListClienti)
{
<option value="@item.IdxCliente">@item.RagSociale</option>
}
</select>
</div>
}
</div>
</div>
</div>
</div>
</div>
</div>
<div class="card-body p-1 small">
@if (ListRecords == null || isLoading)
{
<EgwCoreLib.Razor.LoadingData></EgwCoreLib.Razor.LoadingData>
}
else if (totalCount == 0)
{
<div class="alert alert-info">Nessun record trovato</div>
}
else
{
<table class="table table-striped table-sm text-start small">
<thead>
<tr class="">
<th>
<button class="btn btn-primary btn-sm" @onclick="ForceReload"><i class="fa-solid fa-rotate"></i></button>
</th>
<th>Gruppo <Sorter ParamName="Gruppo" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
<th>RagSoc <Sorter ParamName="RagSoc" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
<th>Nome <Sorter ParamName="NomeProj" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
<th>Real/Bdgt <Sorter ParamName="OreTot" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
<th>Money <Sorter ParamName="Money" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
<th>
</th>
</tr>
</thead>
<tbody>
@if (ShowFasi && RecordSel != null)
{
<tr class="align-middle @CheckSel(RecordSel)">
<td>
<button class="btn btn-secondary btn-sm" disabled><i class="fa-solid fa-search"></i></button>
<button class="btn btn-secondary btn-sm" disabled><i class="fa-solid fa-edit"></i></button>
<button class="btn btn-secondary btn-sm" disabled><i class="fa-solid fa-angles-right"></i></button>
</td>
<td>
<div class="fw-bold">
@RecordSel.Gruppo
</div>
</td>
<td>
<div class="fw-bold">
@RecordSel.RagSociale
</div>
</td>
<td>
<div>
<div>@RecordSel.NomeProj</div>
<div class="small">@RecordSel.DescrProj</div>
</div>
</td>
<td>
<div class="text-center py-1 @ColorByVal(RecordSel.totOre, RecordSel.budgetTime)">
<b>@($"{RecordSel.totOre:N2}")</b> / @($"{RecordSel.budgetTime:N0}")
</div>
</td>
<td>
@if (RecordSel.budgetMoney > 0)
{
@($"{RecordSel.budgetMoney:C2}")
}
</td>
<td class="text-end">
<button class="btn btn-secondary btn-sm" disabled><i class="fa-solid fa-trash"></i></button>
</td>
</tr>
}
else
{
@foreach (var item in ListRecords)
{
<tr class="align-middle @CheckSel(item)">
<td>
@if (RecordEdit == null)
{
<button class="btn btn-info btn-sm" @onclick="() => DoSelect(item)"><i class="fa-solid fa-search"></i></button>
<button class="btn btn-primary btn-sm" @onclick="() => DoEdit(item)"><i class="fa-solid fa-edit"></i></button>
<button class="btn btn-warning btn-sm" @onclick="() => DoShowFasi(item)"><i class="fa-solid fa-angles-right"></i></button>
@* <a class="btn btn-warning btn-sm" href="fasi" target="_blank"><i class="fa-solid fa-angles-right"></i></a> *@
}
else
{
<button class="btn btn-secondary btn-sm" disabled><i class="fa-solid fa-search"></i></button>
<button class="btn btn-secondary btn-sm" disabled><i class="fa-solid fa-edit"></i></button>
<button class="btn btn-secondary btn-sm" disabled><i class="fa-solid fa-angles-right"></i></button>
}
</td>
<td>
<div class="fw-bold">
@item.Gruppo
</div>
</td>
<td>
<div class="fw-bold">
@item.RagSociale
</div>
</td>
<td>
<div>
<div>@item.NomeProj</div>
<div class="small">@item.DescrProj</div>
</div>
</td>
<td>
<div class="text-center py-1 @ColorByVal(item.totOre, item.budgetTime)">
<b>@($"{item.totOre:N2}")</b> / @($"{item.budgetTime:N0}")
</div>
</td>
<td>
@if (item.budgetMoney > 0)
{
@($"{item.budgetMoney:C2}")
}
</td>
<td class="text-end">
@if (item.totOre == 0)
{
<button class="btn btn-danger btn-sm" @onclick="() => DoDelete(item)"><i class="fa-solid fa-trash"></i></button>
}
else
{
<button class="btn btn-secondary btn-sm" disabled><i class="fa-solid fa-trash"></i></button>
}
</td>
</tr>
}
}
</tbody>
</table>
}
@if(ShowFasi)
{
<FasiMan ListRecords=@ListFasiSel EC_update=ReloadFasi ShowSelect="false"></FasiMan>
}
</div>
<div class="card-footer">
@if (!ShowFasi)
{
<EgwCoreLib.Razor.DataPager PageSize="@numRecord" currPage="@currPage" numRecordChanged="SetNumRec" numPageChanged="SetPage" totalCount="@totalCount" showLoading="@isLoading"></EgwCoreLib.Razor.DataPager>
}
</div>
</div>
@@ -0,0 +1,499 @@
using EgwCoreLib.Razor;
using GPW.CORE.Data.DbModels;
using GPW.CORE.Data.Services;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.JSInterop;
using NLog;
using static EgwCoreLib.Razor.Toggler;
namespace GPW.CORE.ADM.Components.Compo
{
public partial class ProgettiMan : IDisposable
{
#region Public Methods
public void Dispose()
{
AppMServ.EA_SearchUpdated -= AppMServ_EA_SearchUpdated;
}
#endregion Public Methods
#region Protected Properties
[Inject]
protected MessageService AppMServ { get; set; } = null!;
[Inject]
protected AppAuthService AuthServ { get; set; } = null!;
[Inject]
protected GpwDataService GDataServ { get; set; } = null!;
[Inject]
protected IJSRuntime JSRuntime { get; set; } = null!;
protected List<AnagClientiModel> ListClienti { get; set; } = new List<AnagClientiModel>();
protected List<AnagGruppiModel> ListGruppi { get; set; } = new List<AnagGruppiModel>();
#endregion Protected Properties
#region Protected Methods
protected string CheckSel(CalcOreProgettiModel curItem)
{
string answ = "";
if (RecordEdit != null)
{
answ = curItem.IdxProgetto == RecordEdit.IdxProgetto ? "table-info" : "";
}
// verifico stato attivo
answ += !(curItem.Attivo ?? false) ? " striked" : "";
return answ;
}
protected async Task CreateNew()
{
FullEdit = true;
RecordSel = null;
RecordEdit = new AnagProgettiModel()
{
NomeProj = "__Nuovo Progetto",
DescrProj = "Descrizione nuovo progetto",
Gruppo = "",
IdxCliente = 0,
Attivo = true
};
await InvokeAsync(StateHasChanged);
}
protected async void DoDelete(CalcOreProgettiModel selItem)
{
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Sicuro di voler eliminare il record?"))
return;
isLoading = true;
await Task.Delay(1);
await InvokeAsync(StateHasChanged);
RecordSel = null;
RecordEdit = GDataServ.AnagProjByKey(selItem.IdxProgetto);
bool fatto = await GDataServ.AnagProjDelete(RecordEdit);
if (fatto)
{
await Task.Delay(1);
await GDataServ.AnagProjForceUpdate();
}
RecordEdit = null;
await ReloadData();
await InvokeAsync(StateHasChanged);
}
protected void DoEdit(CalcOreProgettiModel? selItem)
{
FullEdit = true;
ShowFasi = false;
RecordSel = null;
RecordEdit = GDataServ.AnagProjByKey(selItem.IdxProgetto);
}
protected async Task DoRecalc()
{
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Sicuro di voler forzare il ricalcolo dei record?"))
return;
isLoading = true;
await Task.Delay(1);
await InvokeAsync(StateHasChanged);
await GDataServ.AnagProjForceUpdate();
await Task.Delay(1);
await ReloadData();
}
protected void DoSelect(CalcOreProgettiModel? selItem)
{
FullEdit = false;
ShowFasi = false;
RecordSel = selItem;
RecordEdit = null;
}
protected async Task DoShowFasi(CalcOreProgettiModel? selItem)
{
FullEdit = false;
// carico le fasi e le asso al controllo!
ListFasiSel = await GDataServ.AnagFasiExplByProj(selItem.IdxProgetto);
ShowFasi = true;
RecordSel = selItem;
RecordEdit = null;
}
protected async Task ForceReload()
{
await salvaFiltToggle();
await salvaFiltGrpCli();
FullEdit = false;
ShowFasi = false;
RecordEdit = null;
RecordSel = null;
currPage = 1;
await ReloadData();
}
/// <summary>
/// init valori da config
/// </summary>
/// <returns></returns>
protected async Task initConf()
{
// leggo conf standard controllo RegAtt
var sWarningRatioPerc = await GDataServ.ConfigGetKey("WarningRatioPerc");
if (sWarningRatioPerc != null)
{
double.TryParse(sWarningRatioPerc.valore, out warnRatio);
}
}
protected override async Task OnInitializedAsync()
{
await initConf();
CurrSearch = "";
AppMServ.SearchVal = "";
AppMServ.EA_SearchUpdated += AppMServ_EA_SearchUpdated;
// recupero preferenze utente...
await InitUserPref();
}
protected override async Task OnParametersSetAsync()
{
await ReloadData();
}
protected async Task ReloadFasi()
{
// rileggo fasi associate...
ListFasiSel = new List<AnagFasiExplModel>();
await Task.Delay(1);
//await InvokeAsync(StateHasChanged);
// carico le fasi e le asso al controllo!
ListFasiSel = await GDataServ.AnagFasiExplByProj(RecordSel.IdxProgetto);
await Task.Delay(1);
//await InvokeAsync(StateHasChanged);
}
protected async Task SetNumRec(int newNum)
{
numRecord = newNum;
currPage = 1;
await AppMServ.NumRowGridSet(gridKey, newNum);
await InvokeAsync(ReloadData);
}
protected async Task SetPage(int newNum)
{
currPage = newNum;
await InvokeAsync(ReloadData);
}
protected async Task SortRequested(Sorter.SortCallBack e)
{
sortField = e.ParamName;
sortAsc = e.IsAscending;
await ReloadData();
}
protected string UserLang
{
get => AppMServ.UserLang;
}
protected string Traduci(string lemma)
{
return AuthServ.Traduci(lemma, UserLang);
}
#endregion Protected Methods
#region Private Fields
private static Logger Log = LogManager.GetCurrentClassLogger();
private bool FullEdit = false;
private string gridKey = "ProgettiMan";
private AnagProgettiModel? RecordEdit = null;
private CalcOreProgettiModel? RecordSel = null;
private bool ShowFasi = false;
private bool sortAsc = true;
private string sortField = "";
private double warnRatio = 50;
#endregion Private Fields
#region Private Properties
private int currPage { get; set; } = 1;
private string CurrSearch { get; set; } = "";
private string Gruppo { get; set; } = "";
private int IdxCliente { get; set; } = 0;
private bool isLoading { get; set; } = false;
private List<AnagFasiExplModel>? ListFasiSel { get; set; } = null;
private List<CalcOreProgettiModel>? ListRecords { get; set; } = null;
private string modalSize
{
get => FullEdit ? "modal-xl" : "";
}
private int numRecord { get; set; } = 10;
private List<CalcOreProgettiModel>? SearchRecords { get; set; } = null;
private string SelCliText
{
get => ShowCli ? "Elimina Filt." : "Filt.Clienti";
}
private string SelGrpText
{
get => ShowGruppo ? "Elimina Filt." : "Filt.Gruppo";
}
private bool ShowCli { get; set; } = false;
private bool ShowGruppo { get; set; } = false;
private bool ShowPrjArc { get; set; } = false;
private bool ShowPrjStr { get; set; } = false;
private bool ShowPrjZH { get; set; } = true;
private int totalCount { get; set; } = 0;
#endregion Private Properties
#region Private Methods
private async void AppMServ_EA_SearchUpdated()
{
CurrSearch = AppMServ.SearchVal;
await ReloadData();
await InvokeAsync(StateHasChanged);
}
/// <summary>
/// restituisce una classe css a seconda dei valori passati:
/// green: bdgt &gt; real
/// orange: real &gt; bdgt*warning
/// red: real &gt; bdgt
/// std: errore...
/// </summary>
/// <param name="real"></param>
/// <param name="bdgt"></param>
/// <returns></returns>
private string ColorByVal(object real, object bdgt)
{
string specClass = "default";
try
{
double valoreReal = Convert.ToDouble(real);
double valoreBdget = Convert.ToDouble(bdgt);
double valoreWarn = Convert.ToDouble(bdgt) * warnRatio / 100;
if (valoreReal >= valoreBdget)
{
specClass = "danger";
}
else if (valoreReal >= valoreWarn)
{
specClass = "warning";
}
else
{
specClass = "success";
}
}
catch
{ }
return $" bg-{specClass} bg-opacity-50 bg-gradient border border-{specClass} rounded";
}
private async Task FixFilt()
{
if (!ShowGruppo)
{
Gruppo = "";
}
if (!ShowCli)
{
IdxCliente = 0;
}
currPage = 1;
await salvaFiltGrpCli();
await ReloadData();
}
/// <summary>
/// Init preferenze utente
/// </summary>
/// <returns></returns>
private async Task InitUserPref()
{
try
{
numRecord = await AppMServ.NumRowGridGet(gridKey);
ShowPrjArc = await AppMServ.UserPrefGet<bool>("ShowPrjArc");
ShowPrjStr = await AppMServ.UserPrefGet<bool>("ShowPrjStr");
ShowPrjZH = await AppMServ.UserPrefGet<bool>("ShowPrjZH");
ShowGruppo = await AppMServ.UserPrefGet<bool>("ShowGruppo");
ShowCli = await AppMServ.UserPrefGet<bool>("ShowCli");
Gruppo = await AppMServ.UserPrefGet<string>("Gruppo") ?? "";
IdxCliente = await AppMServ.UserPrefGet<int>("IdxCliente");
}
catch (Exception exc)
{
Log.Error($"Eccezione in InitUserPref{Environment.NewLine}{exc}");
}
}
private async Task ReloadData()
{
isLoading = true;
ListRecords = null;
ListGruppi = await GDataServ.AnagGruppiAll();
ListClienti = await GDataServ.AnagClientiAll();
try
{
SearchRecords = await GDataServ.AnagProjCalcFilt(Gruppo, IdxCliente, ShowPrjArc, ShowPrjZH, ShowPrjStr);
// verifico filtro per ricerca
if (!string.IsNullOrEmpty(CurrSearch))
{
SearchRecords = SearchRecords
.Where(x => x.NomeProj.Contains(CurrSearch, StringComparison.InvariantCultureIgnoreCase)
|| x.DescrProj.Contains(CurrSearch, StringComparison.InvariantCultureIgnoreCase))
.ToList();
}
}
catch (Exception ex)
{
Log.Error($"Eccezione in recupero dati{Environment.NewLine}{ex}");
}
totalCount = SearchRecords.Count;
SortTable();
isLoading = false;
}
private async Task salvaFiltGrpCli()
{
// salvo
await AppMServ.UserPrefSet("ShowGruppo", $"{ShowGruppo}");
await AppMServ.UserPrefSet("ShowCli", $"{ShowCli}");
await AppMServ.UserPrefSet("Gruppo", $"{Gruppo}");
await AppMServ.UserPrefSet("IdxCliente", $"{IdxCliente}");
}
private async Task salvaFiltToggle()
{
// salvo le preferenze...
await AppMServ.UserPrefSet("ShowPrjArc", $"{ShowPrjArc}");
await AppMServ.UserPrefSet("ShowPrjStr", $"{ShowPrjStr}");
await AppMServ.UserPrefSet("ShowPrjZH", $"{ShowPrjZH}");
}
private void SortTable()
{
if (SearchRecords != null)
{
// se ho ordinamento riordino...
if (!string.IsNullOrEmpty(sortField))
{
switch (sortField)
{
case "Gruppo":
if (sortAsc)
{
SearchRecords = SearchRecords.OrderBy(x => x.Gruppo).ToList();
}
else
{
SearchRecords = SearchRecords.OrderByDescending(x => x.Gruppo).ToList();
}
break;
case "RagSoc":
if (sortAsc)
{
SearchRecords = SearchRecords.OrderBy(x => x.RagSociale).ToList();
}
else
{
SearchRecords = SearchRecords.OrderByDescending(x => x.RagSociale).ToList();
}
break;
case "NomeProj":
if (sortAsc)
{
SearchRecords = SearchRecords.OrderBy(x => x.NomeProj).ToList();
}
else
{
SearchRecords = SearchRecords.OrderByDescending(x => x.NomeProj).ToList();
}
break;
case "OreTot":
if (sortAsc)
{
SearchRecords = SearchRecords.OrderBy(x => x.totOre).ToList();
}
else
{
SearchRecords = SearchRecords.OrderByDescending(x => x.totOre).ToList();
}
break;
case "Money":
if (sortAsc)
{
SearchRecords = SearchRecords.OrderBy(x => x.budgetMoney).ToList();
}
else
{
SearchRecords = SearchRecords.OrderByDescending(x => x.budgetMoney).ToList();
}
break;
default:
break;
}
}
// filtro x display
ListRecords = SearchRecords
.Skip(numRecord * (currPage - 1))
.Take(numRecord)
.ToList();
}
else
{
ListRecords = new List<CalcOreProgettiModel>();
}
}
#endregion Private Methods
}
}
@@ -0,0 +1,42 @@
<div class="card shadow">
<div class="card-header">
<h5>Record Commesse</h5>
</div>
<div class="card-body py-0 px-2">
@if (ListRecord == null || ListRecord.Count == 0)
{
<div class="alert alert-info p-2 my-1">Nessun record trovato</div>
}
else
{
<table class="table table-sm table-striped table-responsive-md">
<thead>
<tr>
<th>Dettaglio</th>
</tr>
</thead>
<tbody>
@foreach (var item in ListRecord)
{
<tr>
<td>
<div class="d-flex justify-content-between">
<div class="px-0"><b>@item.FasiNav.ProgettoNav.ClienteNav.RagSociale</b> | @item.FasiNav.ProgettoNav.NomeProj</div>
<div class="badge text-bg-dark">@($"{item.Inizio:HH:mm}") - @($"{item.Fine:HH:mm}")</div>
</div>
<div class="d-flex justify-content-between">
<div class="px-0 text-success">@item.FasiNav.DescrizioneFase</div>
<div class="px-0">@($"{item.Durata.TotalHours:N2} h")</div>
</div>
<div class="d-flex">
<div class="px-0 small">@item.Descrizione</div>
</div>
</td>
</tr>
}
</tbody>
</table>
}
</div>
</div>
@@ -0,0 +1,76 @@
using GPW.CORE.Data.DbModels;
using Microsoft.AspNetCore.Components;
namespace GPW.CORE.ADM.Components.Compo
{
public partial class RAList
{
#region Public Properties
[Parameter]
public EventCallback<RegAttivitaModel> EC_ReqDelete { get; set; }
[Parameter]
public EventCallback<RegAttivitaModel> EC_ReqUpdate { get; set; }
[Parameter]
public bool EnableDelete { get; set; } = false;
[Parameter]
public bool EnableEdit { get; set; } = false;
[Parameter]
public List<RegAttivitaModel>? ListRecord
{
get => listRec;
set => listRec = value;
}
#endregion Public Properties
#region Protected Properties
protected List<RegAttivitaModel>? listRec
{
get
{
return _ListRec;
}
set
{
if (value != null)
{
_ListRec = value.OrderBy(x => x.Inizio).ToList();
}
else
{
_ListRec = null;
}
}
}
#endregion Protected Properties
#region Protected Methods
protected async void Delete(RegAttivitaModel currRecord)
{
await EC_ReqDelete.InvokeAsync(currRecord);
}
protected override async Task OnParametersSetAsync()
{
await InvokeAsync(StateHasChanged);
}
#endregion Protected Methods
#region Private Properties
private List<RegAttivitaModel>? _ListRec { get; set; } = new List<RegAttivitaModel>();
#endregion Private Properties
}
}
@@ -0,0 +1,138 @@
@if (isLoading)
{
<LoadingData></LoadingData>
}
else
{ @if (isSendingData)
{
<ProgressDisplay Title="Salvataggio ed invio richiesta" CurrVal="@sendDataVal" NextVal="@sendDataNextVal" MaxVal="@sendDataMaxVal" ExpTimeMSec="1000"></ProgressDisplay>
}
@if (ListRecords == null)
{
<LoadingData DisplaySize="LoadingData.CtrlSize.Small"></LoadingData>
}
else
{
@if (showAdd)
{
<ul class="list-group">
<li class="list-group-item">
<div class="d-flex justify-content-between">
<div class="px-0">
<b>Inizio Malattia</b>
</div>
<div class="px-2">
@($"{currRecord.DtInizio:yyyy-MM-dd dddd}")
</div>
</div>
</li>
<li class="list-group-item">
<div class="d-flex justify-content-between">
<div class="px-0">
<b>Giorni Malattia</b>
</div>
<div class="px-2">
@currRecord.NumGG
</div>
</div>
</li>
<li class="list-group-item">
<div class="d-flex justify-content-between">
<div class="px-0">
<b>Codice Certificato (INPS)</b>
</div>
<div class="px-2">
@currRecord.CodCert
</div>
</div>
</li>
<li class="list-group-item">
<div class="d-flex justify-content-between">
<div class="px-0">
<b>Stato</b>
<span class="small">(confermato)</span>
</div>
<div class="px-0">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" @bind="@currRecord.Conf">
</div>
</div>
</div>
</li>
<li class="list-group-item">
<div class="row">
<div class="col">
<button class="btn btn-warning w-100" @onclick="() => ToggleEdit()"><i class="fas fa-window-close"></i> Cancel</button>
</div>
<div class="col">
@if (currRecord.CodCert != "")
{
<button class="btn btn-success w-100" @onclick="() => DoSave()"><i class="far fa-save"></i> Update</button>
}
else
{
<button class="btn btn-secondary w-100" disabled><i class="far fa-save"></i> Update</button>
}
</div>
</div>
</li>
</ul>
}
@if (ListRecords.Count == 0)
{
<div class="alert alert-warning">
<h4>Nessu record registrato!</h4>
<button class="btn btn-success btn-sm" @onclick="() => ToggleEdit()"><i class="fas fa-plus"></i> Inserisci Malattia</button>
</div>
}
else
{
<table class="table table-sm table-striped table-responsive-md border border-dark">
<thead>
<tr class="bg-dark text-light">
<th>
<button class="btn btn-success btn-sm" @onclick="() => ToggleEdit()"><i class="fas fa-plus"></i></button>
</th>
<th>Data</th>
<th class="text-center">Giorni</th>
<th class="text-end">Codice</th>
<th class="text-end"></th>
</tr>
</thead>
<tbody>
@foreach (var item in ListRecords)
{
<tr>
<td class="text-nowrap">
@item.DipNav.Abbrev
</td>
<td>
@item.DtInizio.ToString("dd MMM yyyy"), <b>@item.DtInizio.ToString("dddd")</b>
</td>
<td class="text-center">
@item.NumGG
</td>
<td class="text-end">
@item.CodCert
</td>
<td class="text-end">
@if (!item.Conf)
{
<button class="btn btn-success btn-sm" @onclick="() => DoApprove(item)"><i class="fa-solid fa-thumbs-up"></i></button>
}
else
{
<button class="btn btn-primary btn-sm" @onclick="() => DoEdit(item)"><i class="fas fa-pen"></i></button>
}
</td>
</tr>
}
</tbody>
</table>
<div>
<EgwCoreLib.Razor.DataPager PageSize="@numRecord" currPage="@currPage" numRecordChanged="SetNumRec" numPageChanged="SetPage" totalCount="@totalCount" showLoading="@isLoading" NumPages="10" PageSizeList="@PageSizeListSpec"></EgwCoreLib.Razor.DataPager>
</div>
}
}
}
@@ -0,0 +1,224 @@
using GPW.CORE.Data.DbModels;
using GPW.CORE.Data.Services;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using NLog;
namespace GPW.CORE.ADM.Components.Compo
{
public partial class RegMalattia
{
#region Public Properties
[Parameter]
public DateTime DtEnd { get; set; } = new DateTime(DateTime.Today.Year + 1, 1, 1);
[Parameter]
public DateTime DtStart { get; set; } = new DateTime(DateTime.Today.Year, 1, 1);
[Parameter]
public bool isLoading { get; set; }
[Parameter]
public EventCallback<bool> ReportUpdate { get; set; }
#endregion Public Properties
#region Protected Fields
protected List<int> PageSizeListSpec = new List<int>() { 5, 10, 15, 20 };
#endregion Protected Fields
#region Protected Properties
[Inject]
protected MessageService AppMServ { get; set; } = null!;
[Inject]
protected GpwDataService GDataServ { get; set; } = null!;
[Inject]
protected IJSRuntime JSRuntime { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected override async Task OnInitializedAsync()
{
// recupero preferenze utente...
await InitUserPref();
}
protected override async Task OnParametersSetAsync()
{
currPage = 1;
await ReloadData();
}
protected async Task SetNumRec(int newNum)
{
numRecord = newNum;
currPage = 1;
await AppMServ.NumRowGridSet(gridKey, newNum);
await InvokeAsync(ReloadData);
}
protected async Task SetPage(int newNum)
{
currPage = newNum;
await InvokeAsync(ReloadData);
}
#endregion Protected Methods
#region Private Fields
private static Logger Log = LogManager.GetCurrentClassLogger();
private string gridKey = "RegMalattie";
private bool isSendingData = false;
private List<RegMalattieModel>? ListRecords = null;
private List<RegMalattieModel>? SearchRecords = null;
private int sendDataMaxVal = 100;
private int sendDataNextVal = 0;
private int sendDataVal = 0;
private bool showAdd = false;
#endregion Private Fields
#region Private Properties
private int currPage { get; set; } = 1;
private RegMalattieModel currRecord { get; set; } = new RegMalattieModel();
private string NomeDip
{
get
{
string answ = "per cortesia";
if (AppMServ != null && AppMServ.RigaDip != null)
{
answ = $"{AppMServ.RigaDip.Nome}";
}
return answ;
}
}
private int numRecord { get; set; } = 10;
private int totalCount { get; set; } = 0;
#endregion Private Properties
#region Private Methods
private async Task DoApprove(RegMalattieModel selItem)
{
// chiedo verifica
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Confermi approvazione?"))
return;
await Task.Delay(1);
isSendingData = true;
sendDataVal = 0;
sendDataNextVal = 5;
await Task.Delay(1);
await InvokeAsync(StateHasChanged);
// effettuo insert...
sendDataVal = 5;
sendDataNextVal = 90;
await Task.Delay(1);
await GDataServ.RegMalattieApprova(selItem);
sendDataVal = 100;
sendDataNextVal = 100;
await ReloadData();
await Task.Delay(1);
await ReportUpdate.InvokeAsync(true);
isSendingData = false;
}
private void DoEdit(RegMalattieModel selItem)
{
currRecord = selItem;
showAdd = true;
}
/// <summary>
/// Registra il record
/// </summary>
/// <returns></returns>
private async Task DoSave()
{
// chiedo verifica
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Confermi modifica record?"))
return;
isSendingData = true;
sendDataVal = 0;
sendDataNextVal = 5;
await Task.Delay(1);
// effettuo insert...
sendDataVal = 5;
sendDataNextVal = 90;
await Task.Delay(1);
await GDataServ.RegMalattieAppRif(currRecord);
// effettuo insert...
sendDataVal = 100;
sendDataNextVal = 100;
// aggiorno display...
await Task.Delay(1);
showAdd = false;
await ReloadData();
await ReportUpdate.InvokeAsync(true);
isSendingData = false;
}
/// <summary>
/// Init preferenze utente
/// </summary>
/// <returns></returns>
private async Task InitUserPref()
{
try
{
numRecord = await AppMServ.NumRowGridGet(gridKey);
}
catch (Exception exc)
{
Log.Error($"Eccezione in InitUserPref{Environment.NewLine}{exc}");
}
}
private async Task ReloadData()
{
SearchRecords = null;
await Task.Delay(1);
SearchRecords = await GDataServ.RegMalattieGetByPeriod(DtStart, DtEnd);
// conteggio!
totalCount = SearchRecords.Count;
// paginazione
ListRecords = SearchRecords
.OrderByDescending(x => x.DtInizio)
.Skip(numRecord * (currPage - 1))
.Take(numRecord)
.ToList();
await Task.Delay(1);
await InvokeAsync(StateHasChanged);
}
private void ToggleEdit()
{
showAdd = !showAdd;
}
#endregion Private Methods
}
}
@@ -0,0 +1,212 @@
@if (isLoading)
{
<LoadingData></LoadingData>
}
else
{
@if (isSendingData)
{
<ProgressDisplay Title="Salvataggio ed invio richiesta" CurrVal="@sendDataVal" NextVal="@sendDataNextVal" MaxVal="@sendDataMaxVal" ExpTimeMSec="1000"></ProgressDisplay>
}
@if (ListRecords == null)
{
<LoadingData DisplaySize="LoadingData.CtrlSize.Small"></LoadingData>
}
else
{
@if (showAdd)
{
<ul class="list-group">
<li class="list-group-item">
<div class="d-flex justify-content-between">
<div class="px-0">
<b>Causale</b>
</div>
<div class="px-0">
<div class="input-group input-group-sm">
<select @bind="@CodGiust" class="form-select">
<option value="">--- Selezionare Causale ---</option>
@if (ListGiust != null)
{
@foreach (var giust in ListGiust)
{
<option value="@giust.codGiust">@giust.descrizione</option>
}
}
</select>
</div>
</div>
</div>
</li>
<li class="list-group-item">
<div class="d-flex justify-content-between">
<div class="px-0">
<b>Inizio Periodo</b>
</div>
<div class="px-2">
@if (@CodGiust == "PERM" || @CodGiust == "104")
{
@($"{dtStart:yyyy-MM-dd HH:mm}")
}
else
{
@($"{dtStart:yyyy-MM-dd}")
}
</div>
</div>
</li>
<li class="list-group-item">
<div class="d-flex justify-content-between">
<div class="px-0">
<b>Fine Periodo</b>
</div>
<div class="px-2">
@if (@CodGiust == "PERM" || @CodGiust == "104")
{
@($"{dtEnd:yyyy-MM-dd HH:mm}")
}
else
{
@($"{dtEnd:yyyy-MM-dd}")
}
</div>
</div>
</li>
<li class="list-group-item">
<div class="d-flex justify-content-between">
<div class="px-0">
<b>Note</b>
</div>
<div class="px-0">
<textarea class="form-control" @bind="@currRecord.Note" style="width: 20rem;" />
</div>
</div>
</li>
<li class="list-group-item">
<div class="d-flex justify-content-between">
<div class="px-0">
<b>Stato</b>
<span class="small">(confermato)</span>
</div>
<div class="px-0">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" @bind="@currRecord.Conf">
</div>
</div>
</div>
</li>
<li class="list-group-item">
<div class="row">
<div class="col">
<button class="btn btn-warning w-100" @onclick="toggleEdit"><i class="fas fa-window-close"></i> Cancel</button>
</div>
<div class="col">
@if (CodGiust != "")
{
<button class="btn btn-success w-100" @onclick="() => DoSave()"><i class="far fa-save"></i> Save</button>
}
else
{
<button class="btn btn-secondary w-100" disabled><i class="far fa-save"></i> Causale!</button>
}
</div>
</div>
</li>
</ul>
}
@if (ListRecords.Count == 0)
{
<div class="alert alert-warning d-flex justify-content-between">
<div>
Nessu record registrato
</div>
</div>
}
else
{
<table class="table table-sm table-striped table-responsive-md border border-dark">
<thead>
<tr class="bg-dark text-light align-middle">
<th></th>
<th>Dipendente</th>
<th>Periodo</th>
<th class="text-end"></th>
</tr>
</thead>
<tbody>
@foreach (var item in ListRecords)
{
<tr>
<td>
@if (!item.Conf)
{
<button class="btn btn-primary btn-sm" @onclick="() => DoEdit(item)">
<b>@item.CodGiustTrim</b>
</button>
}
else
{
<div class="btn btn-sm btn-secondary disabled">
<b>@item.CodGiustTrim</b>
</div>
}
</td>
<td>
<div class="fs-5">@item.DipNav.Abbrev</div>
</td>
<td>
<div>
@if (item.CodGiust == "PERM")
{
<div class="d-flex justify-content-between pe-2">
<div>
@item.DtStart.ToString("dd MMM yyyy"), <b>@item.DtStart.ToString("HH:mm")</b>
<i class="fas fa-caret-right"></i>
<b>@item.DtEnd.ToString("HH:mm")</b>
</div>
<div>
<b>@item.Durata</b>
</div>
</div>
}
else
{
<div class="d-flex justify-content-between pe-2">
<div>
<b>@item.DtStart.ToString("dd MMM")</b> @item.DtStart.ToString("yyyy")
<i class="fas fa-caret-right"></i>
<b>@item.DtEnd.ToString("dd MMM")</b> @item.DtEnd.ToString("yyyy")
</div>
<div>
<b>@item.Durata</b>
</div>
</div>
}
</div>
<div class="small">
@item.Note
</div>
</td>
<td class="text-end">
@if (!item.Conf)
{
<button class="btn btn-success btn-sm" @onclick="() => DoApprove(item)"><i class="fa-solid fa-thumbs-up"></i></button>
}
else
{
<button class="btn btn-primary btn-sm" @onclick="() => DoEdit(item)">
<i class="fa-solid fa-pen-to-square"></i>
</button>
}
</td>
</tr>
}
</tbody>
</table>
<div>
<EgwCoreLib.Razor.DataPager PageSize="@numRecord" currPage="@currPage" numRecordChanged="SetNumRec" numPageChanged="SetPage" totalCount="@totalCount" showLoading="@isLoading" NumPages="10" PageSizeList="@PageSizeListSpec"></EgwCoreLib.Razor.DataPager>
</div>
}
}
}
@@ -0,0 +1,389 @@
using GPW.CORE.Data.DbModels;
using GPW.CORE.Data.Services;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using NLog;
using static EgwCoreLib.Razor.Toggler;
namespace GPW.CORE.ADM.Components.Compo
{
public partial class RegRichieste
{
#region Public Properties
[Parameter]
public bool isLoading
{
get => loading;
set => loading = value;
}
[Parameter]
public int months { get; set; }
[Parameter]
public EventCallback<bool> ReportUpdate { get; set; }
[Parameter]
public bool ShowNeedConf { get; set; } = false;
#endregion Public Properties
#region Protected Fields
protected List<int> PageSizeListSpec = new List<int>() { 5, 10, 15, 20 };
#endregion Protected Fields
#region Protected Properties
[Inject]
protected MessageService AppMServ { get; set; } = null!;
[Inject]
protected GpwDataService GDataServ { get; set; } = null!;
[Inject]
protected IJSRuntime JSRuntime { get; set; } = null!;
protected bool loading
{
get => _loading;
set
{
if (_loading != value)
{
_loading = value;
var pUpd = Task.Run(async () => await ReloadData());
pUpd.Wait();
}
}
}
#endregion Protected Properties
#region Protected Methods
protected override async Task OnInitializedAsync()
{
ToggleData = new SelectGlobalToggle()
{
leftString = "Da approvare",
rightString = "Tutti",
placardCss = "bg-dark border-dark text-light"
};
dtInizio = new DateTime(DateTime.Today.Year, 1, 1);
dtFine = dtInizio.AddYears(2);
CodGiust = "";
var rawGiust = await GDataServ.AnagGiust();
if (rawGiust != null)
{
ListGiust = rawGiust.Where(x => x.showReq).ToList();
}
// recupero preferenze utente...
await InitUserPref();
}
protected override async Task OnParametersSetAsync()
{
currPage = 1;
await ReloadData();
}
protected async Task SetNumRec(int newNum)
{
numRecord = newNum;
currPage = 1;
await AppMServ.NumRowGridSet(gridKey, newNum);
await InvokeAsync(ReloadData);
}
protected async Task SetPage(int newNum)
{
currPage = newNum;
await InvokeAsync(ReloadData);
}
#endregion Protected Methods
#region Private Fields
private static Logger Log = LogManager.GetCurrentClassLogger();
private string gridKey = "RegRichieste";
private bool isSendingData = false;
private List<AnagGiustModel>? ListGiust = null;
private List<RegRichiesteModel>? ListRecords = null;
/// <summary>
/// Numero giorni minimo per richiesta ferie
/// </summary>
private int NumDayFerieRichAntic = 14;
/// <summary>
/// NUmero giorni massimo per richiesta permessi
/// </summary>
private int NumDayPermMax = 21;
private List<RegRichiesteModel>? SearchRecords = null;
private int sendDataMaxVal = 100;
private int sendDataNextVal = 0;
private int sendDataVal = 0;
private bool showAdd = false;
#endregion Private Fields
#region Private Properties
private bool _loading { get; set; } = false;
private string CodGiust
{
get => currRecord.CodGiust;
set
{
currRecord.CodGiust = value;
}
}
private int currPage { get; set; } = 1;
private RegRichiesteModel currRecord { get; set; } = new RegRichiesteModel();
private DateTime dtEnd
{
get => currRecord.DtEnd;
set
{
currRecord.DtEnd = value;
// verifico coerenza date...
if (dtStart > dtEnd)
{
dtStart = dtEnd;
}
}
}
private DateTime dtFine { get; set; } = DateTime.Today;
private DateTime dtInizio { get; set; } = DateTime.Today;
private DateTime dtStart
{
get => currRecord.DtStart;
set
{
currRecord.DtStart = value;
// verifico coerenza date...
if (dtEnd < dtStart)
{
dtEnd = dtStart;
}
}
}
private string NomeDip
{
get
{
string answ = "per cortesia";
if (AppMServ != null && AppMServ.RigaDip != null)
{
answ = $"{AppMServ.RigaDip.Nome}";
}
return answ;
}
}
private int numRecord { get; set; } = 10;
private SelectGlobalToggle ToggleData { get; set; } = new SelectGlobalToggle();
private int totalCount { get; set; } = 0;
#endregion Private Properties
#region Private Methods
private async Task DoApprove(RegRichiesteModel selItem)
{
// chiedo verifica
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Confermi approvazione?"))
return;
// imposto approvato...
selItem.Conf = true;
await Task.Delay(1);
isSendingData = true;
sendDataVal = 0;
sendDataNextVal = 5;
await Task.Delay(1);
await InvokeAsync(StateHasChanged);
// effettuo insert...
sendDataVal = 5;
sendDataNextVal = 90;
await Task.Delay(1);
await GDataServ.RegRichiesteAppRif(selItem);
sendDataVal = 100;
sendDataNextVal = 100;
await ReloadData();
await Task.Delay(1);
await ReportUpdate.InvokeAsync(true);
isSendingData = false;
}
private async Task DoEdit(RegRichiesteModel selItem)
{
// chiedo conferma se è scaduto..
if (selItem.DtStart < DateTime.Today)
{
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Sei sicuro di voler modificare un record di una richiesta passata?"))
return;
}
currRecord = selItem;
showAdd = true;
}
/// <summary>
/// Salva il record
/// </summary>
/// <returns></returns>
private async Task DoSave()
{
// chiedo verifica
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Confermi la modifica?"))
return;
isSendingData = true;
sendDataVal = 0;
sendDataNextVal = 5;
await Task.Delay(1);
// effettuo insert...
sendDataVal = 5;
sendDataNextVal = 90;
await Task.Delay(1);
// uso metodo specifico x modifica
await GDataServ.RegRichiesteAppRif(currRecord);
sendDataVal = 100;
sendDataNextVal = 100;
await Task.Delay(1);
showAdd = false;
await ReloadData();
await ReportUpdate.InvokeAsync(true);
isSendingData = false;
}
private async Task evToggled(SelectGlobalToggle newTogData)
{
ToggleData = newTogData;
await ReloadData();
}
/// <summary>
/// init valori da config
/// </summary>
/// <returns></returns>
private async Task initConf()
{
// leggo conf standard giorni permessi/ferie
var sNumDayFerieRichAntic = await GDataServ.ConfigGetKey("NumDayFerieRichAntic");
if (sNumDayFerieRichAntic != null)
{
int.TryParse(sNumDayFerieRichAntic.valore, out NumDayFerieRichAntic);
}
var sNumDayPermMax = await GDataServ.ConfigGetKey("NumDayPermMax");
if (sNumDayPermMax != null)
{
int.TryParse(sNumDayPermMax.valore, out NumDayPermMax);
}
}
/// <summary>
/// Init preferenze utente
/// </summary>
/// <returns></returns>
private async Task InitUserPref()
{
try
{
numRecord = await AppMServ.NumRowGridGet(gridKey);
}
catch (Exception exc)
{
Log.Error($"Eccezione in InitUserPref{Environment.NewLine}{exc}");
}
}
private DateTime maxDate(string codGiust)
{
DateTime answ = DateTime.Today.AddDays(NumDayPermMax);
switch (codGiust)
{
case "FER":
answ = new DateTime(answ.Year, answ.Month, 1).AddMonths(months);
break;
case "104":
case "PERM":
default:
DateTime.Today.AddDays(NumDayPermMax);
break;
}
return answ;
}
private DateTime minDate(string codGiust)
{
DateTime answ = DateTime.Today;
switch (codGiust)
{
case "FER":
answ = DateTime.Today.AddDays(NumDayFerieRichAntic);
break;
case "104":
case "PERM":
default:
answ = DateTime.Today;
break;
}
return answ;
}
private async Task ReloadData()
{
ListRecords = null;
await initConf();
await Task.Delay(1);
// carico richieste di TUTTI
SearchRecords = await GDataServ.RegRichiesteGetByDip(0, dtInizio, dtFine);
// filtro x tipo richieste...
if (ShowNeedConf)
{
SearchRecords = SearchRecords.Where(x => !x.Conf).ToList();
}
// conteggio!
totalCount = SearchRecords.Count;
// paginazione
ListRecords = SearchRecords
.Skip(numRecord * (currPage - 1))
.Take(numRecord)
.ToList();
}
private void toggleEdit()
{
showAdd = !showAdd;
}
#endregion Private Methods
}
}
@@ -0,0 +1,258 @@
@if (isSendingData)
{
<ProgressDisplay Title="Salvataggio ed invio richiesta" CurrVal="@sendDataVal" NextVal="@sendDataNextVal" MaxVal="@sendDataMaxVal" ExpTimeMSec="8000"></ProgressDisplay>
}
<div class="card shadow">
<div class="card-header">
<div class="d-flex justify-content-between">
<div class="px-0">
<h4>Elenco Timbrature</h4>
</div>
<div class="px-0">
<div class="d-flex align-middle">
<div class="px-1 py-2">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" @bind=@ShowInatt @bind:after=ForceReload>
<label class="form-check-label">Mostra Inattivi</label>
</div>
</div>
<div class="px-1 py-1">
<select @bind="@IdxDipSel" class="form-select form-select-sm" @bind:after=ForceReload>
<option value="0">--- Selezionare ---</option>
@foreach (var item in ListDipendenti)
{
<option value="@item.IdxDipendente">@($"{item.Cognome} {item.Nome}")</option>
}
</select>
</div>
</div>
</div>
<div class="px-0">
<div class="d-flex">
<div class="px-1">
<PeriodoSel CurrPeriodo="@CurrPeriodo" E_PeriodoSel="@SavePeriodo"></PeriodoSel>
</div>
<div class="px-1 py-2">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" @bind=@ShowWE @bind:after=ForceReload>
<label class="form-check-label">Mostra Week-End</label>
</div>
</div>
</div>
</div>
<div class="px-0 d-flex">
<div class="px-0">
<button class="btn btn-sm btn-success" title="Ricalcola" @onclick="DoFullRecalc">&sum; (h)</button>
</div>
<div class="px-0">
<button class="btn btn-sm btn-info mx-1" title="Export Ore" @onclick=SaveExpOre><i class="fa-solid fa-rotate"></i> Exp.Ore</button>
</div>
<div class="px-0">
<button class="btn btn-sm btn-primary" title="Export Commesse" @onclick=SaveExpCom><i class="fa-solid fa-rotate"></i> Exp.Com.</button>
</div>
</div>
</div>
</div>
<div class="card-body p-1 small">
@if (ListRecords == null || isLoading)
{
<EgwCoreLib.Razor.LoadingData></EgwCoreLib.Razor.LoadingData>
}
else if (totalCount == 0)
{
<div class="alert alert-info">Nessun record trovato</div>
}
else
{
<div class="row">
<div class="col-8">
<table class="table table-striped table-sm text-start">
<thead>
<tr class="">
<th>
<button class="btn btn-info btn-sm" @onclick="ForceReload"><i class="fa-solid fa-rotate"></i></button>
</th>
<th>Dipendente <Sorter ParamName="Dipendente" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
<th>Data <Sorter ParamName="DataLav" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
<th class="text-center">IN</th>
<th class="text-center">OUT</th>
<th class="text-center">IN</th>
<th class="text-center">OUT</th>
<th class="text-center">IN</th>
<th class="text-center">OUT</th>
<th class="text-center">IN</th>
<th class="text-center">OUT</th>
<th class="text-end">H Lav</th>
<th class="text-end">H Giu</th>
<th class="text-end">T/C19</th>
<th class="text-end">Tag</th>
<th class="text-end">Chk</th>
<th class="text-end">H Com</th>
</tr>
</thead>
<tbody>
@foreach (var item in ListRecords)
{
<tr class="align-middle lh-1 @CheckSel(item)">
<td>
<button class="btn btn-info btn-sm" @onclick="() => DoSelect(item)"><i class="fa-solid fa-search"></i></button>
</td>
<td class="fs-5">
@item.CognomeNome
</td>
<td>
<div>
@($"{item.DataLav:yyyy.MM.dd}")
</div>
<div>
@($"{item.DataLav:dddd}")
</div>
</td>
<td class="text-center text-success">
@if (item.entrata_1 != null)
{
@($"{item.entrata_1:HH:mm}")
}
</td>
<td class="text-center text-primary">
@if (item.uscita_1 != null)
{
@($"{item.uscita_1:HH:mm}")
}
</td>
<td class="text-center text-success">
@if (item.entrata_2 != null)
{
@($"{item.entrata_2:HH:mm}")
}
</td>
<td class="text-center text-primary">
@if (item.uscita_2 != null)
{
@($"{item.uscita_2:HH:mm}")
}
</td>
<td class="text-center text-success">
@if (item.entrata_3 != null)
{
@($"{item.entrata_3:HH:mm}")
}
</td>
<td class="text-center text-primary">
@if (item.uscita_3 != null)
{
@($"{item.uscita_3:HH:mm}")
}
</td>
<td class="text-center text-success">
@if (item.entrata_4 != null)
{
@($"{item.entrata_4:HH:mm}")
}
</td>
<td class="text-center text-primary">
@if (item.uscita_4 != null)
{
@($"{item.uscita_4:HH:mm}")
}
</td>
<td class="text-end fs-4 fw-bold">
@($"{item.h_lav:N2}")
</td>
<td class="text-end">
@if (item.h_giust > 0)
{
@($"{item.h_giust:N2}")
}
</td>
<td class="text-end">
@if (item.TempRil < 34)
{
<i class="fa-solid fa-temperature-low text-secondary"></i>
}
else if (item.TempRil < 37)
{
<i class="fa-solid fa-temperature-low text-success"></i>
}
else if (item.TempRil < (decimal)37.5)
{
<i class="fa-solid fa-temperature-low text-warning"></i>
}
else
{
<i class="fa-solid fa-temperature-low text-danger"></i>
}
</td>
<td class="text-end">
@if (!item.TagIsActive)
{
<span class="striked text-secondary">@item.CodTag</span>
}
else
{
@item.CodTag
}
</td>
<td class="text-end fw-bold">
@if (!item.isOkTim)
{
<span class="text-danger" tooltip="Errore Entrata/Uscita: non corrispondono.">T</span>
}
@if (!item.isOkApp)
{
<span class="text-danger" tooltip="Errore: timbrature non approvate.">A</span>
}
@if (item.isOkLav == 0)
{
<span class="text-danger" tooltip="Errore: manca copertura ore ordinarie.">O</span>
}
@if (!string.IsNullOrEmpty(item.chkFunCod))
{
<span tooltip="@item.chkFunRes">@item.minMpp</span>
}
@if (item.isOk != 0)
{
<span class="text-success" tooltip="Tutto OK.">Ok</span>
}
</td>
<td class="text-end fs-4 fw-bold">
@if (item.okLAvCom != 0)
{
<span class="text-dark">@($"{item.h_com:N2}")</span>
}
else
{
<span class="text-warning">@($"{item.h_com:N2}")</span>
}
</td>
</tr>
}
</tbody>
</table>
</div>
<div class="col-4">
@if (SelRecord != null)
{
<div class="py-1">
<TimbList ListRecord="@ListTimbDay" EnableDelete="true" EnableEdit="true" EC_ReqUpdate="TimbUpdate" EC_ReqDelete="TimbDelete"></TimbList>
</div>
<div class="py-3">
<GiustList ListRecord="@ListGiustDay" ListGiust="@ListGiust" EnableEdit="true" EnableDelete="true" EC_ReqUpdate="GiustUpdate" EC_ReqDelete="GiustDelete" EC_ReqAddNew="GiustAddNew" EC_ReqCancel="GiustCancel"></GiustList>
</div>
<div class="py-1">
<RAList ListRecord="@ListRA" EnableDelete="false" EnableEdit="false"></RAList>
</div>
}
</div>
</div>
}
</div>
<div class="card-footer">
<EgwCoreLib.Razor.DataPager PageSize="@numRecord" currPage="@currPage" numRecordChanged="SetNumRec" numPageChanged="SetPage" totalCount="@totalCount" showLoading="@isLoading" PageSizeList="@PageSizeListSpec"></EgwCoreLib.Razor.DataPager>
</div>
</div>
@@ -0,0 +1,544 @@
using EgwCoreLib.Razor;
using GPW.CORE.Data.DbModels;
using GPW.CORE.Data.Services;
using GPW.CORE.Data;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using NLog;
using EgwCoreLib.Utils;
using System.Diagnostics;
using static GPW.CORE.ADM.Components.Compo.GiustList;
using static System.Runtime.InteropServices.JavaScript.JSType;
namespace GPW.CORE.ADM.Components.Compo
{
public partial class ReviewTimbMan : IDisposable
{
#region Public Methods
public void Dispose()
{
AppMServ.EA_SearchUpdated -= AppMServ_EA_SearchUpdated;
}
#endregion Public Methods
#region Protected Fields
protected List<int> PageSizeListSpec = new List<int>() { 5, 10, 15, 20, 25, 50 };
#endregion Protected Fields
#region Protected Properties
[Inject]
protected MessageService AppMServ { get; set; } = null!;
[Inject]
protected IConfiguration config { get; set; } = null!;
[Inject]
protected GpwDataService GDataServ { get; set; } = null!;
protected int IdxDipSel { get; set; } = 0;
[Inject]
protected IJSRuntime JSRuntime { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected string CheckSel(TeRaExplModel? SelItem)
{
string answ = "";
if (SelRecord != null)
{
answ = SelRecord.UID == SelItem.UID ? "table-info" : "";
}
return answ;
}
protected async Task DoSelect(TeRaExplModel selItem)
{
// seleziono record x mostrare update
SelRecord = selItem;
await ReloadDayDetail();
await Task.Delay(1);
}
protected async Task ForceReload()
{
currPage = 1;
SelRecord = null;
await ReloadData();
await ReloadDayDetail();
}
protected async Task GiustAddNew(string CodGiust)
{
if (SelRecord != null)
{
await GDataServ.GiustificativiInsByDate(SelRecord.IdxDipendente, SelRecord.DataLav, CodGiust);
await ReloadData();
await ReloadDayDetail();
}
}
protected async Task GiustCancel()
{
await ReloadData();
await ReloadDayDetail();
}
protected async Task GiustDelete(GiustificativiModel selItem)
{
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Sicuro di voler eliminare il record Giustificativo?"))
return;
await GDataServ.GiustificativiDelete(selItem);
await ReloadData();
await ReloadDayDetail();
}
protected async Task GiustUpdate(GiustSet newSet)
{
await GDataServ.GiustificativiUpdate(newSet.OldRec, newSet.NewRec);
await ReloadData();
await ReloadDayDetail();
}
protected override async Task OnInitializedAsync()
{
CurrPeriodo.Fine = DateTime.Today.AddDays(1);
CurrSearch = "";
AppMServ.SearchVal = "";
AppMServ.EA_SearchUpdated += AppMServ_EA_SearchUpdated;
numRecord = await AppMServ.NumRowGridGet(gridKey);
ListGiust = await GDataServ.AnagGiust();
// imposto path...
exportPath = config.GetValue<string>("ServerConf:BasePathExport") ?? config.GetValue<string>("OptConf:BasePathExport") ?? $"{Directory.GetCurrentDirectory()}\\temp\\";
// svuoto temp folder dopo 1 min
await clearDir(1);
// carico conf specifica...
var rCodTimbra = await GDataServ.ConfigGetKey("ExpOreCodTimbra");
if (rCodTimbra != null)
{
TimbExp = rCodTimbra.valore;
}
}
protected override async Task OnParametersSetAsync()
{
await ReloadData();
}
protected async Task SetNumRec(int newNum)
{
numRecord = newNum;
currPage = 1;
await AppMServ.NumRowGridSet(gridKey, newNum);
await InvokeAsync(ReloadData);
}
protected async Task SetPage(int newNum)
{
currPage = newNum;
await InvokeAsync(ReloadData);
}
protected async Task SortRequested(Sorter.SortCallBack e)
{
sortField = e.ParamName;
sortAsc = e.IsAscending;
await ReloadData();
}
protected async Task TimbDelete(TimbratureModel selItem)
{
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Sicuro di voler eliminare il record Timbratura?"))
return;
await GDataServ.TimbratureDelete(selItem);
await ReloadData();
await ReloadDayDetail();
//SelRecord = null;
//await InvokeAsync(StateHasChanged);
}
protected async Task TimbUpdate(TimbratureModel UpdRec)
{
await GDataServ.TimbratureUpdate(UpdRec);
await ReloadData();
await ReloadDayDetail();
}
#endregion Protected Methods
#region Private Fields
private static Logger Log = LogManager.GetCurrentClassLogger();
private string gridKey = "RevTimbMan";
private int sendDataMaxVal = 100;
private int sendDataNextVal = 0;
private int sendDataVal = 0;
private bool sortAsc = true;
private string sortField = "";
#endregion Private Fields
#region Private Properties
private int currPage { get; set; } = 1;
private DtUtils.Periodo CurrPeriodo { get; set; } = new DtUtils.Periodo(DtUtils.PeriodSet.ThisMonth);
private string CurrSearch { get; set; } = "";
private string exportPath { get; set; } = "";
private bool filtDip { get; set; } = false;
private string fnExpComm
{
get => $"ExportCommesse_{DateTime.Now:yyyyMMdd}_{DateTime.Now:HHmmss}.csv";
}
private string fnTimb
{
get => $"Timbrature_{DateTime.Now:yyyyMMdd}_{DateTime.Now:HHmmss}.csv";
}
private bool isLoading { get; set; } = false;
private bool isSendingData { get; set; } = false;
private List<DipendentiModel> ListDipendenti { get; set; } = new List<DipendentiModel>();
private List<AnagGiustModel>? ListGiust { get; set; } = null;
private List<GiustificativiModel>? ListGiustDay { get; set; } = null;
private List<RegAttivitaModel>? ListRA { get; set; } = null;
private List<TeRaExplModel>? ListRecords { get; set; } = null;
private List<TimbratureModel>? ListTimbDay { get; set; } = null;
private int MaxErrMin { get; set; } = -30;
private int MaxErrPlus { get; set; } = 30;
private int numRecord { get; set; } = 10;
private List<TeRaExplModel>? SearchRecords { get; set; } = null;
private TeRaExplModel? SelRecord { get; set; } = null;
private bool ShowInatt { get; set; } = false;
private bool ShowWE { get; set; } = true;
private string TimbExp { get; set; } = "000";
private int totalCount { get; set; } = 0;
#endregion Private Properties
#region Private Methods
private async void AppMServ_EA_SearchUpdated()
{
CurrSearch = AppMServ.SearchVal;
await ReloadData();
await InvokeAsync(StateHasChanged);
}
private async Task clearDir(int maxAgeMinutes)
{
string dirPath = Path.Combine(exportPath);
DirectoryInfo dInfo = new DirectoryInfo(dirPath);
await Task.Run(() =>
{
var fileList = dInfo.GetFiles();
// elimino file + vecchi de minuti ricevuti...
foreach (var file in fileList)
{
if (file.CreationTime < DateTime.Now.AddMinutes(-maxAgeMinutes))
{
file.Delete();
}
}
});
}
private bool ClearFile(string fileName)
{
bool fatto = false;
string filePath = Path.Combine(exportPath, fileName);
if (File.Exists(filePath))
{
File.Delete(exportPath);
fatto = true;
}
return fatto;
}
/// <summary>
/// ricalcola giornate periodo visualizzato per i dipendenti selezionati
/// </summary>
private async Task DoFullRecalc()
{
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Sicuro di voler ricalcolare il periodo selezionato? L'operazione richiederà tempo..."))
return;
Stopwatch sw = new Stopwatch();
sw.Start();
Log.Trace($"DoFullRecalc | Starting");
isSendingData = true;
await Task.Delay(1);
sendDataVal = 0;
sendDataNextVal = 50;
await InvokeAsync(StateHasChanged);
// step 1: ricalcola timb esplose x utenti e periodo...
var updTask = Task.Run(async () =>
await GDataServ.TimbExplRicalcola(IdxDipSel, CurrPeriodo.Inizio, CurrPeriodo.Fine)
);
await updTask;
sw.Stop();
Log.Info($"DoFullRecalc | STEP 01 | {sw.ElapsedMilliseconds:N0} ms");
sw.Restart();
sendDataVal = 50;
sendDataNextVal = 90;
await InvokeAsync(StateHasChanged);
// verifico dip con giust da inserire...
var list2fix = await GDataServ.TimbExplGetAnomalie(IdxDipSel, CurrPeriodo.Inizio, CurrPeriodo.Fine, false, false, true);
if (list2fix != null && list2fix.Count > 0)
{
var updTask2 = Task.Run(async () =>
{
foreach (var item in list2fix)
{
// escludo date da oggi in poi...
if (item.DataLav < DateTime.Today)
{
GiustificativiModel rec2del = new GiustificativiModel()
{
IdxDipendente = item.IdxDipendente,
DataLav = item.DataLav,
CodGiust = "PERM"
};
try
{
// elimino eventuali vecchi permessi
await GDataServ.GiustificativiDelete(rec2del);
// inserisco permessi...
await GDataServ.GiustificativiInsByDate(item.IdxDipendente, item.DataLav, "PERM");
}
catch (Exception exc)
{
Log.Error($"Eccezione in ricalcolo:{Environment.NewLine}{exc}");
}
}
}
sw.Stop();
Log.Info($"DoFullRecalc | STEP 02 | {sw.ElapsedMilliseconds:N0} ms");
sw.Restart();
// ricalcolo!
await GDataServ.TimbExplRicalcola(IdxDipSel, CurrPeriodo.Inizio, CurrPeriodo.Fine);
sw.Stop();
Log.Info($"DoFullRecalc | STEP 03 | {sw.ElapsedMilliseconds:N0} ms");
sw.Restart();
});
sw.Stop();
await updTask2;
Log.Info($"DoFullRecalc | STEP 04 | {sw.ElapsedMilliseconds:N0} ms");
sw.Restart();
}
sendDataVal = 90;
sendDataNextVal = 100;
await InvokeAsync(StateHasChanged);
// ricalcolo RegAttExpl
var updTask3 = Task.Run(async () =>
{
await GDataServ.RegAttRicalcola(IdxDipSel, CurrPeriodo.Inizio, CurrPeriodo.Fine);
});
await updTask3;
sw.Stop();
Log.Info($"DoFullRecalc | STEP 05 | {sw.ElapsedMilliseconds:N0} ms");
// aggiorno
SelRecord = null;
sendDataVal = 100;
sendDataNextVal = 100;
isLoading = true;
await Task.Delay(1);
await InvokeAsync(StateHasChanged);
await ReloadData();
}
private async Task ExportCsv<T>(string fileName, List<T> RecList)
{
isLoading = true;
if (RecList != null)
{
string filePath = Path.Combine(exportPath, fileName);
// salvo davvero!
await Utils.SaveToCsv(RecList, filePath, ';');
}
isLoading = false;
}
private async Task ExportTxt(string fileName, List<string> RecList)
{
isLoading = true;
if (RecList != null)
{
string filePath = Path.Combine(exportPath, fileName);
await File.WriteAllLinesAsync(filePath, RecList);
}
isLoading = false;
}
private async Task ReloadData()
{
isLoading = true;
ListRecords = null;
var rawList = await GDataServ.DipendentiGetAll();
if (ShowInatt)
{
ListDipendenti = rawList;
}
else
{
ListDipendenti = rawList.Where(x => (x.Attivo ?? false)).ToList();
}
try
{
SearchRecords = await GDataServ.TeRaExplGetFilt(IdxDipSel, CurrPeriodo.Inizio, CurrPeriodo.Fine, ShowInatt, ShowWE, MaxErrMin, MaxErrPlus);
// verifico filtro per IdxDip
if (IdxDipSel > 0)
{
SearchRecords = SearchRecords.Where(x => x.IdxDipendente == IdxDipSel).ToList();
}
}
catch (Exception ex)
{
Log.Error($"Eccezione in recupero dati{Environment.NewLine}{ex}");
}
totalCount = SearchRecords.Count;
SortTable();
isLoading = false;
// tolgo eventuale send data...
isSendingData = false;
}
private async Task ReloadDayDetail()
{
if (SelRecord != null)
{
// salvo dettaglio giornaliero
ListTimbDay = await GDataServ.TimbratureDay(SelRecord.DataLav, SelRecord.IdxDipendente);
ListGiustDay = await GDataServ.GiustificativiFilt(SelRecord.IdxDipendente, SelRecord.DataLav, SelRecord.DataLav.AddDays(1).AddMinutes(-1));
ListRA = await GDataServ.RegAttDipDate(SelRecord.IdxDipendente, SelRecord.DataLav);
}
}
private async Task SaveExpCom()
{
// svuoto
ClearFile(fnExpComm);
// recupero nuovo elenco dati...
var list2save = await GDataServ.ExportCommessa(IdxDipSel, CurrPeriodo.Inizio, CurrPeriodo.Fine);
if (list2save != null)
{
// bonifica descrizione: elimino gli a capo...
foreach (var item in list2save)
{
if (item.Descrizione.Contains(Environment.NewLine) || item.Descrizione.Contains("\n") || item.Descrizione.Contains("\r"))
{
item.Descrizione = item.Descrizione.Replace(Environment.NewLine, " ").Replace("\n", " ").Replace("\r", " ");
}
}
// export
await ExportCsv(fnExpComm, list2save);
// chiamo apri pagina x download
await JSRuntime.InvokeVoidAsync("open", $"export/{fnExpComm}", "_blank");
}
}
private async Task SaveExpOre()
{
// svuoto
ClearFile(fnTimb);
// recupero nuovo elenco dati elenco zucchetti
var rawData = await GDataServ.ExportZucchetti(IdxDipSel, CurrPeriodo.Inizio, CurrPeriodo.Fine, TimbExp);
var list2save = rawData.Select(x => x.CampoExport).ToList();
if (list2save != null)
{
// export
await ExportTxt(fnTimb, list2save);
// chiamo apri pagina x download
await JSRuntime.InvokeVoidAsync("open", $"export/{fnTimb}", "_blank");
}
}
private async Task SavePeriodo(DtUtils.Periodo newPeiodo)
{
CurrPeriodo = newPeiodo;
await ReloadData();
}
private void SortTable()
{
if (SearchRecords != null)
{
// se ho ordinamento riordino...
if (!string.IsNullOrEmpty(sortField))
{
switch (sortField)
{
case "Dipendente":
if (sortAsc)
{
SearchRecords = SearchRecords.OrderBy(x => x.CognomeNome).ToList();
}
else
{
SearchRecords = SearchRecords.OrderByDescending(x => x.CognomeNome).ToList();
}
break;
case "DataLav":
if (sortAsc)
{
SearchRecords = SearchRecords.OrderBy(x => x.DataLav).ToList();
}
else
{
SearchRecords = SearchRecords.OrderByDescending(x => x.DataLav).ToList();
}
break;
default:
break;
}
}
// filtro x display
ListRecords = SearchRecords
.Skip(numRecord * (currPage - 1))
.Take(numRecord)
.ToList();
}
else
{
ListRecords = new List<TeRaExplModel>();
}
}
#endregion Private Methods
}
}
@@ -0,0 +1,73 @@

<div class="card shadow">
<div class="card-header">
<div class="d-flex justify-content-between">
<div class="px-0">
<h3>@Traduci("SpostaFasi")</h3>
</div>
<div class="px-0 align-content-center">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" @bind=@ShowPrjArc>
<label class="form-check-label">Mostra Archiviati (Clienti/Progetti)</label>
</div>
</div>
</div>
</div>
<div class="card-body p-1">
<div class="row my-1">
@if (OkFase)
{
<div class="col-3">
<button class="btn btn-primary w-100" @onclick=SpostaFase>Sposta Fase</button>
</div>
<div class="col-3">
<button class="btn btn-success w-100" @onclick=ClonaFase>Clona Fase</button>
</div>
}
else
{
<div class="col-3">
<button class="btn btn-secondary w-100" disabled>Sposta Fase</button>
</div>
<div class="col-3">
<button class="btn btn-secondary w-100" disabled>Clona Fase</button>
</div>
}
@if (OkSubFase)
{
<div class="col-3">
<button class="btn btn-primary w-100" @onclick=SpostaSubFase>Sposta SottoFase</button>
</div>
<div class="col-3">
<button class="btn btn-success w-100" @onclick=ClonaSubFase>Clona SottoFase</button>
</div>
}
else
{
<div class="col-3">
<button class="btn btn-secondary w-100" disabled>Sposta SottoFase</button>
</div>
<div class="col-3">
<button class="btn btn-secondary w-100" disabled>Clona SottoFase</button>
</div>
}
</div>
<div class="row">
@if (isLoading)
{
<div class="col-12">
<LoadingData DisplaySize="LoadingData.CtrlSize.Large"></LoadingData>
</div>
}
else
{
<div class="col-6">
<FasiMan Title="Origine" HeadCss="bg-info bg-opacity-75 bg-gradient" CanSelProj="true" ShowOnlyActive="!ShowPrjArc" EC_FaseSel="SetFaseOrig"></FasiMan>
</div>
<div class="col-6">
<FasiMan Title="Destinazione" HeadCss="bg-success bg-opacity-75 bg-gradient" CanSelProj="true" ShowOnlyActive="!ShowPrjArc" EC_FaseSel="SetFaseDest" EC_ProjSel="SetProjDest"></FasiMan>
</div>
}
</div>
</div>
</div>
@@ -0,0 +1,116 @@
using GPW.CORE.Data.DbModels;
using GPW.CORE.Data.Services;
using Microsoft.AspNetCore.Components;
namespace GPW.CORE.ADM.Components.Compo
{
public partial class SpostaFasiMan
{
#region Protected Properties
[Inject]
protected MessageService AppMServ { get; set; } = null!;
[Inject]
protected AppAuthService AuthServ { get; set; } = null!;
[Inject]
protected GpwDataService GDataServ { get; set; } = null!;
protected bool OkFase
{
get => selFaseOrig != null && selFaseOrig.IdxFaseAncest == 0 && selFaseDest == null && selIdxProjDest > 0;
}
protected bool OkSubFase
{
get => selFaseOrig != null && selFaseOrig.IdxFaseAncest != 0 && selFaseDest != null && selFaseDest.IdxFaseAncest == 0;
}
#endregion Protected Properties
#region Protected Methods
protected async Task ClonaFase()
{
isLoading = true;
if (selFaseOrig != null)
{
await GDataServ.AnagFasiDupFase(selIdxProjDest, selFaseOrig.IdxFase);
}
await Task.Delay(100);
isLoading = false;
}
protected async Task ClonaSubFase()
{
isLoading = true;
if (selFaseOrig != null && selFaseDest != null)
{
await GDataServ.AnagFasiDupSubFase(selFaseDest.IdxFase, selFaseOrig.IdxFase);
}
await Task.Delay(100);
isLoading = false;
}
protected void SetFaseDest(AnagFasiExplModel selFase)
{
selFaseDest = selFase;
}
protected void SetFaseOrig(AnagFasiExplModel selFase)
{
selFaseOrig = selFase;
}
protected void SetProjDest(int idxProj)
{
selIdxProjDest = idxProj;
}
protected async Task SpostaFase()
{
isLoading = true;
if (selFaseOrig != null)
{
await GDataServ.AnagFasiMovFase(selIdxProjDest, selFaseOrig.IdxFase);
}
await Task.Delay(100);
isLoading = false;
}
protected async Task SpostaSubFase()
{
isLoading = true;
if (selFaseOrig != null && selFaseDest != null)
{
await GDataServ.AnagFasiMovSubFase(selFaseDest.IdxFase, selFaseOrig.IdxFase);
}
await Task.Delay(100);
isLoading = false;
}
protected string Traduci(string lemma)
{
return AuthServ.Traduci(lemma, AppMServ.UserLang);
}
#endregion Protected Methods
#region Private Fields
private bool isLoading = false;
private bool ShowPrjArc = false;
#endregion Private Fields
#region Private Properties
private AnagFasiExplModel? selFaseDest { get; set; } = null;
private AnagFasiExplModel? selFaseOrig { get; set; } = null;
private int selIdxProjDest { get; set; } = 0;
#endregion Private Properties
}
}
@@ -0,0 +1,30 @@
<div class="row g-1">
<div class="col-md-3">
<div class="form-floating">
<input type="text" class="form-control" @bind="@CurrRecord.CodGruppo">
<label class="small">Gruppo</label>
</div>
</div>
<div class="col-md-5">
<div class="form-floating">
<input type="text" class="form-control" @bind="@CurrRecord.Descrizione">
<label class="small">Descrizione</label>
</div>
</div>
<div class="col-md-1">
<div class="form-floating">
<span class="form-control">
<div class="form-check form-switch">
<input type="checkbox" class="form-check-input" @bind="@CurrRecord.Enabled">
</div>
</span>
<label class="small">Att.</label>
</div>
</div>
<div class="col-md-3 pt-2">
<button class="btn btn-success w-100" @onclick="() => DoSave()"><i class="fas fa-floppy-disk"></i> Save</button>
<button class="btn btn-warning w-100" @onclick="() => DoCancel()"><i class="fas fa-ban"></i> Cancel</button>
</div>
</div>
@@ -0,0 +1,48 @@
using GPW.CORE.Data.DbModels;
using GPW.CORE.Data.DTO;
using GPW.CORE.Data.Services;
using Microsoft.AspNetCore.Components;
namespace GPW.CORE.ADM.Components.Compo
{
public partial class TagsEdit
{
#region Public Properties
[Parameter]
public TagFasiDTO? CurrRecord { get; set; } = null;
[Parameter]
public EventCallback<bool> EC_update { get; set; }
#endregion Public Properties
#region Protected Properties
[Inject]
protected GpwDataService GDataServ { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected async Task DoSave()
{
bool fatto = false;
await Task.Delay(1);
if (CurrRecord != null)
{
fatto = await GDataServ.AnagTagFasiUpsert(CurrRecord);
}
await EC_update.InvokeAsync(fatto);
}
protected async Task DoCancel()
{
await EC_update.InvokeAsync(true);
}
#endregion Protected Methods
}
}
+112
View File
@@ -0,0 +1,112 @@
@if (SelItem != null)
{
<div class="modal fade show" tabindex="-1" style="display:block; background-color: rgba(10,10,10,.6);" aria-modal="true" role="dialog" data-keyboard="true">
<div class="modal-dialog modal-xl">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Edit Etichetta <b>@SelItem.CodTagFase</b></h4>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" @onclick="() => ForceReload(true)"></button>
</div>
<div class="modal-body p-1 small">
<TagsEdit CurrRecord=@SelItem EC_update="ForceReload"></TagsEdit>
</div>
</div>
</div>
</div>
}
<div class="card shadow">
<div class="card-header">
<div class="d-flex">
<div class="px-0">
<h3>Gestione Etichette</h3>
</div>
<div class="px-2">
<button class="btn btn-success" @onclick=CreateNew tooltip="Add New"><i class="fa-solid fa-plus"></i> Add New</button>
</div>
</div>
</div>
<div class="card-body p-1 small">
@if (ListRecords == null || isLoading)
{
<EgwCoreLib.Razor.LoadingData></EgwCoreLib.Razor.LoadingData>
}
else if (totalCount == 0)
{
<div class="alert alert-info">Nessun record trovato</div>
}
else
{
<table class="table table-striped table-sm text-start">
<thead>
<tr class="">
<th>
<button class="btn btn-primary btn-sm" @onclick="() => ForceReload(true)"><i class="fa-solid fa-rotate"></i></button>
</th>
<th>Etichetta <Sorter ParamName="CodTagFase" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
<th>Gruppo <Sorter ParamName="CodGruppo" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
<th>Descrizione <Sorter ParamName="Descrizione" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
<th>Att. <Sorter ParamName="PICF" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
<th class="text-end"><Sorter ParamName="NumFasi" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter> # Fasi</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in ListRecords)
{
<tr class="align-middle @CheckSel(item)">
<td>
@if (SelItem == null)
{
<button class="btn btn-primary btn-sm" @onclick="() => DoEdit(item)"><i class="fa-solid fa-edit"></i></button>
}
else
{
<button class="btn btn-secondary btn-sm" disabled><i class="fa-solid fa-edit"></i></button>
}
</td>
<td>
@item.CodTagFase
</td>
<td>
@item.CodGruppo
</td>
<td>
@item.Descrizione
</td>
<td>
@if (item.Enabled)
{
<i class="fa-solid fa-certificate text-success"></i>
}
else
{
<i class="fa-solid fa-certificate text-secondary"></i>
}
</td>
<td class="text-end">
@item.NumFasi
</td>
<td>
@if (item.Enabled && item.NumFasi == 0)
{
<button class="btn btn-danger btn-sm" @onclick="() => DoDelete(item)"><i class="fa-solid fa-trash"></i></button>
}
else
{
<button class="btn btn-secondary btn-sm" disabled><i class="fa-solid fa-trash"></i></button>
}
</td>
</tr>
}
</tbody>
</table>
}
</div>
<div class="card-footer">
<EgwCoreLib.Razor.DataPager PageSize="@numRecord" currPage="@currPage" numRecordChanged="SetNumRec" numPageChanged="SetPage" totalCount="@totalCount" showLoading="@isLoading"></EgwCoreLib.Razor.DataPager>
</div>
</div>
@@ -0,0 +1,245 @@
using EgwCoreLib.Razor;
using GPW.CORE.Data.DbModels;
using GPW.CORE.Data.DTO;
using GPW.CORE.Data.Services;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using NLog;
using static EgwCoreLib.Razor.Toggler;
namespace GPW.CORE.ADM.Components.Compo
{
public partial class TagsMan : IDisposable
{
#region Public Methods
public void Dispose()
{
AppMServ.EA_SearchUpdated -= AppMServ_EA_SearchUpdated;
}
#endregion Public Methods
#region Protected Properties
[Inject]
protected MessageService AppMServ { get; set; } = null!;
[Inject]
protected GpwDataService GDataServ { get; set; } = null!;
[Inject]
protected IJSRuntime JSRuntime { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected string CheckSel(TagFasiDTO curItem)
{
string answ = "";
if (SelItem != null)
{
answ = curItem.CodTagFase == SelItem.CodTagFase ? "table-info" : "";
}
// verifico stato attivo
answ += !curItem.Enabled ? " striked" : "";
return answ;
}
protected async Task CreateNew()
{
SelItem = new TagFasiDTO()
{
CodTagFase = "_COD0000",
Descrizione = $"Nuova Tag Fase - {DateTime.Now}",
CodGruppo = "ND",
Enabled = true
};
await InvokeAsync(StateHasChanged);
}
protected async void DoDelete(TagFasiDTO selItem)
{
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Sicuro di voler eliminare il record?"))
return;
isLoading = true;
bool fatto = await GDataServ.AnagTagFasiDelete(selItem);
await ReloadData();
await InvokeAsync(StateHasChanged);
}
protected void DoEdit(TagFasiDTO? selItem)
{
SelItem = selItem;
}
protected async Task ForceReload(bool force)
{
SelItem = null;
await ReloadData();
}
protected override async Task OnInitializedAsync()
{
CurrSearch = "";
AppMServ.SearchVal = "";
AppMServ.EA_SearchUpdated += AppMServ_EA_SearchUpdated;
numRecord = await AppMServ.NumRowGridGet(gridKey);
}
protected override async Task OnParametersSetAsync()
{
await ReloadData();
}
protected async Task SetNumRec(int newNum)
{
numRecord = newNum;
currPage = 1;
await AppMServ.NumRowGridSet(gridKey, newNum);
await InvokeAsync(ReloadData);
}
protected async Task SetPage(int newNum)
{
currPage = newNum;
await InvokeAsync(ReloadData);
}
protected async Task SortRequested(Sorter.SortCallBack e)
{
sortField = e.ParamName;
sortAsc = e.IsAscending;
await ReloadData();
}
#endregion Protected Methods
#region Private Fields
private static Logger Log = LogManager.GetCurrentClassLogger();
private string gridKey = "TagsMan";
private TagFasiDTO? SelItem = null;
private bool sortAsc = true;
private string sortField = "";
#endregion Private Fields
#region Private Properties
private int currPage { get; set; } = 1;
private string CurrSearch { get; set; } = "";
private bool isLoading { get; set; } = false;
private List<TagFasiDTO>? ListRecords { get; set; } = null;
private int numRecord { get; set; } = 10;
private List<TagFasiDTO>? SearchRecords { get; set; } = null;
private int totalCount { get; set; } = 0;
#endregion Private Properties
#region Private Methods
private async void AppMServ_EA_SearchUpdated()
{
CurrSearch = AppMServ.SearchVal;
await ReloadData();
await InvokeAsync(StateHasChanged);
}
private async Task ReloadData()
{
isLoading = true;
ListRecords = null;
try
{
SearchRecords = await GDataServ.AnagTagFasiAll();
// verifico filtro per ricerca
if (!string.IsNullOrEmpty(CurrSearch))
{
SearchRecords = SearchRecords.Where(x => x.Descrizione.Contains(CurrSearch, StringComparison.InvariantCultureIgnoreCase)).ToList();
}
}
catch (Exception ex)
{
Log.Error($"Eccezione in recupero dati{Environment.NewLine}{ex}");
}
totalCount = SearchRecords.Count;
SortTable();
isLoading = false;
}
private void SortTable()
{
if (SearchRecords != null)
{
// se ho ordinamento riordino...
if (!string.IsNullOrEmpty(sortField))
{
switch (sortField)
{
case "Descrizione":
if (sortAsc)
{
SearchRecords = SearchRecords.OrderBy(x => x.Descrizione).ToList();
}
else
{
SearchRecords = SearchRecords.OrderByDescending(x => x.Descrizione).ToList();
}
break;
case "CodGruppo":
if (sortAsc)
{
SearchRecords = SearchRecords.OrderBy(x => x.CodGruppo).ToList();
}
else
{
SearchRecords = SearchRecords.OrderByDescending(x => x.CodGruppo).ToList();
}
break;
case "CodTagFase":
if (sortAsc)
{
SearchRecords = SearchRecords.OrderBy(x => x.CodTagFase).ToList();
}
else
{
SearchRecords = SearchRecords.OrderByDescending(x => x.CodTagFase).ToList();
}
break;
case "NumFasi":
if (sortAsc)
{
SearchRecords = SearchRecords.OrderBy(x => x.NumFasi).ToList();
}
else
{
SearchRecords = SearchRecords.OrderByDescending(x => x.NumFasi).ToList();
}
break;
default:
break;
}
}
// filtro x display
ListRecords = SearchRecords
.Skip(numRecord * (currPage - 1))
.Take(numRecord)
.ToList();
}
else
{
ListRecords = new List<TagFasiDTO>();
}
}
#endregion Private Methods
}
}
@@ -0,0 +1,80 @@
@inject DialogService DialogService
<div class="card">
<div class="card-header" style="@($"background: {model.Color}; color: {model.ForeColor};")">
<div class="d-flex justify-content-between">
<div class="px-0">Tipologia:</div>
<div class="px-0"><b>@model.CodTipo</b></div>
</div>
</div>
<ul class="list-group list-group-flush">
<li class="list-group-item">
<div class="d-flex justify-content-between">
<div class="px-0">Nome:</div>
@if (@model.IdxDipendente > 0)
{
<div class="px-0"><b>@model.Abbrev</b></div>
}
else
{
<div class="px-0"><b>@model.Descrizione</b></div>
}
</div>
</li>
@if (model.DtEnd.Subtract(model.DtStart).TotalDays < 1)
{
<li class="list-group-item">
<div class="d-flex justify-content-between">
<div class="px-0">Data:</div>
<div class="px-0"><b>@($"{model.DtStart:ddd yyyy-MM-dd}")</b></div>
</div>
</li>
}
<li class="list-group-item">
<div class="d-flex justify-content-between">
<div class="px-0">Inizio:</div>
<div class="px-0"><b>@(EventDTO.DateForm(model.CodTipo, model.DtStart))</b></div>
</div>
</li>
<li class="list-group-item">
<div class="d-flex justify-content-between">
<div class="px-0">Fine:</div>
<div class="px-0"><b>@(EventDTO.DateForm(model.CodTipo, model.DtEnd))</b></div>
</div>
</li>
@if (model.IdxDipendente == idxDipendente)
{
<li class="list-group-item">
<div class="d-flex justify-content-between">
<div class="px-0">Note:</div>
<div class="px-0"><b>@model.Note</b></div>
</div>
</li>
}
@if(!model.Conf)
{
<li class="list-group-item text-center bg-danger text-warning">
<b>NON CONFERMATO</b>
</li>
}
</ul>
</div>
@code {
[Parameter]
public EventDTO ThisTask { get; set; } = null!;
[Inject]
protected MessageService AppMServ { get; set; } = null!;
EventDTO model = new EventDTO();
protected override void OnParametersSet()
{
model = ThisTask;
}
protected int idxDipendente
{
get => AppMServ.IdxDipendente;
}
}
@@ -0,0 +1,66 @@
<div class="card shadow">
<div class="card-header">
<h5>Timbrature</h5>
</div>
<div class="card-body py-0 px-2">
@if (ListRecord == null || ListRecord.Count == 0)
{
<div class="alert alert-info p-2 my-1">Nessun record trovato</div>
}
else
{
<table class="table table-sm table-striped table-responsive-md">
<thead>
<tr>
<th><i class="fa-solid fa-stopwatch"></i></th>
<th class="text-center" title="Entrata"><i class="fas fa-sign-in-alt"></i></th>
<th class="text-center">Scambio</th>
<th class="text-center" title="Uscita"><i class="fas fa-sign-out-alt"></i></th>
<th class="text-end"></th>
</tr>
</thead>
<tbody>
@foreach (var item in ListRecord)
{
<tr>
<td class="small">@($"{item.DataOra:dd/MM - HH:mm}")</td>
<td title="Entrata" class="text-center">
@if (@item.Entrata == true)
{
<i class="fas fa-times fs-5"></i>
}
</td>
<td class="text-center">
@if (EnableEdit)
{
<button class="btn btn-sm btn-primary" title="Scambio IN/OUT" @onclick="() => ScambioInOut(item)"><i class="fas fa-exchange-alt"></i></button>
}
else
{
<button class="btn btn-sm btn-secondary bg-opacity-50" title="Scambio IN/OUT"><i class="fas fa-exchange-alt"></i></button>
}
</td>
<td title="Uscita" class="text-center">
@if (@item.Entrata == false)
{
<i class="fas fa-times fs-5"></i>
}
</td>
<td class="text-end">
@if (EnableDelete)
{
<button class="btn btn-sm btn-danger" @onclick="() => Delete(item)" title="Elimina Timbratura"><i class="fas fa-trash-alt"></i></button>
}
else
{
<button class="btn btn-sm btn-secondary" disabled><i class="fas fa-trash-alt"></i></button>
}
</td>
</tr>
}
</tbody>
</table>
}
</div>
</div>
@@ -0,0 +1,80 @@
using GPW.CORE.Data.DbModels;
using Microsoft.AspNetCore.Components;
namespace GPW.CORE.ADM.Components.Compo
{
public partial class TimbList
{
#region Public Properties
[Parameter]
public EventCallback<TimbratureModel> EC_ReqDelete { get; set; }
[Parameter]
public EventCallback<TimbratureModel> EC_ReqUpdate { get; set; }
[Parameter]
public bool EnableDelete { get; set; } = false;
[Parameter]
public bool EnableEdit { get; set; } = false;
[Parameter]
public List<TimbratureModel>? ListRecord
{
get => listRec;
set => listRec = value;
}
#endregion Public Properties
#region Protected Properties
protected List<TimbratureModel>? listRec
{
get
{
return _ListRec;
}
set
{
if (value != null)
{
_ListRec = value.OrderByDescending(x => x.DataOra).ToList();
}
else
{
_ListRec = null;
}
}
}
#endregion Protected Properties
#region Protected Methods
protected async void Delete(TimbratureModel currRecord)
{
await EC_ReqDelete.InvokeAsync(currRecord);
}
protected override async Task OnParametersSetAsync()
{
await InvokeAsync(StateHasChanged);
}
protected async void ScambioInOut(TimbratureModel currRecord)
{
currRecord.Entrata = !currRecord.Entrata;
await EC_ReqUpdate.InvokeAsync(currRecord);
}
#endregion Protected Methods
#region Private Properties
private List<TimbratureModel>? _ListRec { get; set; } = new List<TimbratureModel>();
#endregion Private Properties
}
}
+12
View File
@@ -0,0 +1,12 @@

<div class="bg-dark bg-gradient bg-opacity-75 text-light border border-primary d-flex justify-content-around rounded shadow">
<div class="w-25 text-center">
<h1>Working</h1>
<img src="images/wip.png" class="img-fluid"/>
<div class="my-2">More to complete...</div>
</div>
</div>
@code {
}
@@ -0,0 +1,29 @@
@inherits LayoutComponentBase
<div class="page">
<div class="@sideClass">
<NavMenu EC_compressUpdated="@UpdateNavDisplay" />
</div>
<main>
<div class="top-row px-4">
<AuthorizeView>
<LoginDisplay />
</AuthorizeView>
</div>
<article class="content px-4 py-1">
<RadzenComponents @rendermode="@(new InteractiveServerRenderMode(prerender: false))" />
@Body
</article>
<div class="fixed-bottom bottom-row px-2 py-1">
<CmpFooter></CmpFooter>
</div>
</main>
</div>
<div id="blazor-error-ui">
An unhandled error has occurred.
<a href="" class="reload">Reload</a>
<a class="dismiss">🗙</a>
</div>
@@ -0,0 +1,23 @@
namespace GPW.CORE.ADM.Components.Layout
{
public partial class MainLayout
{
#region Protected Properties
protected bool navLarge { get; set; } = true;
protected string sideClass { get; set; } = "sidebar";
#endregion Protected Properties
#region Protected Methods
protected void UpdateNavDisplay()
{
navLarge = !navLarge;
sideClass = navLarge ? "sidebar" : "sidebarSmall";
}
#endregion Protected Methods
}
}
@@ -0,0 +1,78 @@
.page {
position: relative;
display: flex;
flex-direction: column;
}
main {
flex: 1;
}
.sidebar,
.sidebarSmall {
/*background-image: linear-gradient(180deg, rgb(5, 39, 103) 20%, #3aa6ff 90%);*/
background: -webkit-linear-gradient(to bottom, #053787, #A57C00);
/* Chrome 10-25, Safari 5.1-6 */
background: linear-gradient(to bottom, #053787, #A57C00);
/* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
}
.top-row {
background-color: #f7f7f7;
border-bottom: 1px solid #d6d5d5;
/*justify-content: flex-end;*/
height: 3.5rem;
display: flex;
align-items: center;
}
.top-row ::deep a,
.top-row .btn-link {
white-space: nowrap;
margin-left: 1.5rem;
}
.top-row a:first-child {
overflow: hidden;
text-overflow: ellipsis;
}
.bottom-row {
color: #dedede;
background-color: #000000;
height: 1.6rem;
align-items: center;
}
@media (max-width: 640.98px) {
.top-row:not(.auth) {
display: none;
}
.top-row.auth {
justify-content: space-between;
}
.top-row a,
.top-row .btn-link {
margin-left: 0;
}
}
@media (min-width: 641px) {
.page {
flex-direction: row;
}
.sidebar {
width: 13.5rem;
height: 100vh;
position: sticky;
top: 0;
}
.sidebarSmall {
width: 4.5rem;
height: 100vh;
position: sticky;
top: 0;
}
.top-row {
position: sticky;
top: 0;
z-index: 1;
}
.top-row,
article {
padding-left: 0.5rem !important;
padding-right: 0.5rem !important;
}
}
@@ -10,22 +10,21 @@ main {
.sidebar,
.sidebarSmall {
background-image: linear-gradient(180deg, rgb(5, 39, 103) 20%, #3aa6ff 90%);
/*background-image: linear-gradient(180deg, rgb(5, 39, 103) 20%, #3aa6ff 90%);*/
background: -webkit-linear-gradient(to bottom, #053787, #A57C00); /* Chrome 10-25, Safari 5.1-6 */
background: linear-gradient(to bottom, #053787, #A57C00); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
}
.top-row {
background-color: #f7f7f7;
border-bottom: 1px solid #d6d5d5;
justify-content: flex-end;
/*justify-content: flex-end;*/
height: 3.5rem;
display: flex;
align-items: center;
/*justify-content: space-evenly;
display: flex;*/
}
.top-row ::deep a,
.top-row .btn-link {
.top-row ::deep a, .top-row .btn-link {
white-space: nowrap;
margin-left: 1.5rem;
}
@@ -38,7 +37,7 @@ main {
.bottom-row {
color: #dedede;
background-color: #000000;
height: 2rem;
height: 1.6rem;
align-items: center;
}
@@ -46,11 +45,12 @@ main {
.top-row:not(.auth) {
display: none;
}
.top-row.auth {
justify-content: space-between;
}
.top-row a,
.top-row .btn-link {
.top-row a, .top-row .btn-link {
margin-left: 0;
}
}
@@ -59,37 +59,29 @@ main {
.page {
flex-direction: row;
}
.sidebar {
width: 15rem;
width: 13.5rem;
height: 100vh;
position: sticky;
top: 0;
}
.sidebarSmall {
width: 80px;
width: 4.5rem;
height: 100vh;
position: sticky;
top: 0;
}
.top-row {
position: sticky;
top: 0;
z-index: 1;
}
.top-row,
article {
.top-row, article {
padding-left: 0.5rem !important;
padding-right: 0.5rem !important;
}
.bottom-row {
position: fixed;
bottom: 0;
z-index: 1;
}
.main>div {
padding-left: 0.5rem !important;
padding-right: 0.5rem !important;
/*padding-left: 2rem !important;
padding-right: 1.5rem !important;*/
}
}
}
@@ -0,0 +1 @@
.page{position:relative;display:flex;flex-direction:column;}main{flex:1;}.sidebar,.sidebarSmall{background:-webkit-linear-gradient(to bottom,#053787,#a57c00);background:linear-gradient(to bottom,#053787,#a57c00);}.top-row{background-color:#f7f7f7;border-bottom:1px solid #d6d5d5;height:3.5rem;display:flex;align-items:center;}.top-row ::deep a,.top-row .btn-link{white-space:nowrap;margin-left:1.5rem;}.top-row a:first-child{overflow:hidden;text-overflow:ellipsis;}.bottom-row{color:#dedede;background-color:#000;height:1.6rem;align-items:center;}@media(max-width:640.98px){.top-row:not(.auth){display:none;}.top-row.auth{justify-content:space-between;}.top-row a,.top-row .btn-link{margin-left:0;}}@media(min-width:641px){.page{flex-direction:row;}.sidebar{width:13.5rem;height:100vh;position:sticky;top:0;}.sidebarSmall{width:4.5rem;height:100vh;position:sticky;top:0;}.top-row{position:sticky;top:0;z-index:1;}.top-row,article{padding-left:.5rem!important;padding-right:.5rem!important;}}
@@ -0,0 +1,62 @@
<div class="top-row ps-3 navbar navbar-dark">
<div class="container-fluid px-0">
@if (!showText)
{
<a class="navbar-brand p-0" @onclick="() => ToggleCompress()">GPW <i class="fas fa-caret-square-right"></i></a>
}
else
{
<a class="navbar-brand" @onclick="() => ToggleCompress()">GPW.CORE.ADM <i class="fas fa-caret-square-left"></i></a>
}
<button title="Navigation menu" class="navbar-toggler" @onclick="ToggleNavMenu">
<span class="navbar-toggler-icon"></span>
</button>
</div>
</div>
@* <input type="checkbox" title="Navigation menu" class="navbar-toggler" /> *@
@* <div class="nav-scrollable @NavMenuCssClass" onclick="document.querySelector('.navbar-toggler').click()"> *@
<div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
<nav class="flex-column">
<div class="nav-item px-2">
<NavLink class="nav-link" href="Home" Match="NavLinkMatch.All">
<span class="fas fa-home px-2 fs-4" aria-hidden="true"></span>
@if (showText)
{
<span class="@hideText">Home</span>
}
</NavLink>
</div>
<AuthorizeView>
<Authorized>
</Authorized>
<NotAuthorized>
<div class="alert alert-warning">Auth necessaria</div>
</NotAuthorized>
</AuthorizeView>
@if (ListMenu == null || ListMenu.Count == 0)
{
<LoadingData DisplaySize="LoadingData.CtrlSize.Small"></LoadingData>
}
else
{
@foreach (var item in ListMenu)
{
<div class="nav-item px-2">
<NavLink class="nav-link" href="@item.Url">
<span class="@item.Descript px-2 fs-4" aria-hidden="true"></span> <span class="@hideText">@item.Title</span>
</NavLink>
</div>
}
}
<div class="nav-item px-2">
<NavLink class="nav-link" href="ForceReset">
<span class="fas fa-sync-alt px-2 fs-4" aria-hidden="true"></span> <span class="@hideText">Reset Cache</span>
</NavLink>
</div>
</nav>
</div>
@@ -0,0 +1,113 @@
using GPW.CORE.Data.DTO;
using GPW.CORE.Data.Services;
using Microsoft.AspNetCore.Components;
using System.Drawing.Imaging;
namespace GPW.CORE.ADM.Components.Layout
{
public partial class NavMenu : IDisposable
{
#region Public Properties
[Parameter]
public EventCallback<bool> EC_compressUpdated { get; set; }
#endregion Public Properties
#region Public Methods
public void Dispose()
{
AppMServ.EA_MenuUpdated -= AppMServ_EA_MenuUpdated;
AppMServ.EA_LangSel -= AppMServ_EA_LangSel;
}
#endregion Public Methods
#region Protected Properties
[Inject]
protected MessageService AppMServ { get; set; } = null!;
protected string hideText { get => showText ? "" : "invisible"; }
/// <summary>
/// Idx Dipendente corrente
/// </summary>
protected int IdxDipendente
{
get
{
return AppMServ.IdxDipendente;
}
}
protected List<MenuItemDTO> ListMenu { get; set; } = new List<MenuItemDTO>();
protected bool showText { get; set; } = true;
#endregion Protected Properties
#region Protected Methods
protected override void OnInitialized()
{
AppMServ.EA_MenuUpdated += AppMServ_EA_MenuUpdated;
AppMServ.EA_LangSel += AppMServ_EA_LangSel;
ReloadData();
}
private void AppMServ_EA_LangSel()
{
ReloadData();
InvokeAsync(StateHasChanged);
}
protected void ToggleCompress()
{
showText = !showText;
EC_compressUpdated.InvokeAsync(showText);
}
#endregion Protected Methods
#region Private Fields
private bool collapseNavMenu = true;
private bool onlyIcon = false;
#endregion Private Fields
#region Private Properties
private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null;
private string? TextCss => onlyIcon ? "d-none" : "";
#endregion Private Properties
#region Private Methods
private void AppMServ_EA_MenuUpdated()
{
ReloadData();
InvokeAsync(StateHasChanged);
}
private void ReloadData()
{
// rilettura menù se mancasse
ListMenu = AppMServ.ListMenu;
}
private void ToggleNavMenu()
{
collapseNavMenu = !collapseNavMenu;
}
#endregion Private Methods
}
}
@@ -0,0 +1,51 @@
.navbar-toggler {
background-color: rgba(255, 255, 255, 0.1);
}
.top-row {
height: 3.5rem;
background-color: rgba(0, 0, 0, 0.5);
}
.navbar-brand {
font-size: 1.1rem;
}
.oi {
width: 2rem;
font-size: 1.1rem;
vertical-align: text-top;
top: -2px;
}
.nav-item {
font-size: 0.9rem;
padding-bottom: 0.1rem;
}
.nav-item:first-of-type {
padding-top: 0.5rem;
}
.nav-item:last-of-type {
padding-bottom: 0.5rem;
}
.nav-item ::deep a {
color: #d7d7d7;
border-radius: 4px;
height: 2.7rem;
display: flex;
align-items: center;
line-height: 2.7rem;
}
.nav-item ::deep a.active {
background-color: rgba(255, 255, 255, 0.25);
color: white;
}
.nav-item ::deep a:hover {
background-color: rgba(255, 255, 255, 0.1);
color: white;
}
@media (min-width: 641px) {
.navbar-toggler {
display: none;
}
.collapse {
/* Never collapse the sidebar for wide screens */
display: block;
}
}
@@ -0,0 +1,62 @@
.navbar-toggler {
background-color: rgba(255, 255, 255, 0.1);
}
.top-row {
height: 3.5rem;
background-color: rgba(0,0,0,0.5);
}
.navbar-brand {
font-size: 1.1rem;
}
.oi {
width: 2rem;
font-size: 1.1rem;
vertical-align: text-top;
top: -2px;
}
.nav-item {
font-size: 0.9rem;
padding-bottom: 0.1rem;
}
.nav-item:first-of-type {
padding-top: 0.5rem;
}
.nav-item:last-of-type {
padding-bottom: 0.5rem;
}
.nav-item ::deep a {
color: #d7d7d7;
border-radius: 4px;
height: 2.7rem;
display: flex;
align-items: center;
line-height: 2.7rem;
}
.nav-item ::deep a.active {
background-color: rgba(255,255,255,0.25);
color: white;
}
.nav-item ::deep a:hover {
background-color: rgba(255,255,255,0.1);
color: white;
}
@media (min-width: 641px) {
.navbar-toggler {
display: none;
}
.collapse {
/* Never collapse the sidebar for wide screens */
display: block;
}
}
+1
View File
@@ -0,0 +1 @@
.navbar-toggler{background-color:rgba(255,255,255,.1);}.top-row{height:3.5rem;background-color:rgba(0,0,0,.5);}.navbar-brand{font-size:1.1rem;}.oi{width:2rem;font-size:1.1rem;vertical-align:text-top;top:-2px;}.nav-item{font-size:.9rem;padding-bottom:.1rem;}.nav-item:first-of-type{padding-top:.5rem;}.nav-item:last-of-type{padding-bottom:.5rem;}.nav-item ::deep a{color:#d7d7d7;border-radius:4px;height:2.7rem;display:flex;align-items:center;line-height:2.7rem;}.nav-item ::deep a.active{background-color:rgba(255,255,255,.25);color:#fff;}.nav-item ::deep a:hover{background-color:rgba(255,255,255,.1);color:#fff;}@media(min-width:641px){.navbar-toggler{display:none;}.collapse{display:block;}}
@@ -0,0 +1,16 @@
@page "/ApprovTimbrature"
@inject MessageService AppMServ
@inject AppAuthService AuthServ
<ApprovTimbMan></ApprovTimbMan>
@code {
protected override void OnInitialized()
{
// imposto pagina e info testata
AppMServ.ShowSearch = false;
AppMServ.PageName = AuthServ.Traduci("ApprTimb", AppMServ.UserLang);
AppMServ.PageIcon = AuthServ.Traduci("ApprTimbExpl");
}
}
@@ -0,0 +1,7 @@
@page "/CheckC19"
<WIP></WIP>
@code {
}
@@ -0,0 +1,16 @@
@page "/clienti"
@inject MessageService AppMServ
@inject AppAuthService AuthServ
<ClientiMan></ClientiMan>
@code {
protected override void OnInitialized()
{
// imposto pagina e info testata
AppMServ.ShowSearch = true;
AppMServ.PageName = AuthServ.Traduci("ManClienti", AppMServ.UserLang);
AppMServ.PageIcon = AuthServ.Traduci("ManClientiExpl");
}
}
@@ -0,0 +1,7 @@
@page "/Dipendenti"
<WIP></WIP>
@code {
}
+36
View File
@@ -0,0 +1,36 @@
@page "/Error"
@using System.Diagnostics
<PageTitle>Error</PageTitle>
<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>
@if (ShowRequestId)
{
<p>
<strong>Request ID:</strong> <code>@RequestId</code>
</p>
}
<h3>Development Mode</h3>
<p>
Swapping to <strong>Development</strong> environment will display more 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>
@code{
[CascadingParameter]
private HttpContext? HttpContext { get; set; }
private string? RequestId { get; set; }
private bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
protected override void OnInitialized() =>
RequestId = Activity.Current?.Id ?? HttpContext?.TraceIdentifier;
}
@@ -0,0 +1,15 @@
@page "/ForceReset"
@attribute [Authorize]
<div class="card shadow-lg">
<div class="card-header">
Data Reset
</div>
<div class="card-body">
<h1>@message</h1>
<LoadingData Title="Reset Data..." DisplaySize="LoadingData.CtrlSize.Large" DisplayMode="LoadingData.SpinMode.BounceLine"></LoadingData>
</div>
</div>
@@ -0,0 +1,51 @@
using GPW.CORE.Data.Services;
using Microsoft.AspNetCore.Components;
namespace GPW.CORE.ADM.Components.Pages
{
public partial class ForceReset
{
#region Protected Fields
protected string message = "Resetting Cache!";
#endregion Protected Fields
#region Protected Properties
[Inject]
protected MessageService AppMServ { get; set; } = null!;
[Inject]
protected GpwDataService GDataServ { get; set; } = null!;
[Inject]
protected NavigationManager NavManager { get; set; } = null!;
[Inject]
protected AppAuthService AuthService { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected override async Task OnInitializedAsync()
{
await Task.Delay(10);
await GDataServ.FlushRedisCache();
await Task.Delay(10);
await AuthService.FlushRedisCache();
await Task.Delay(10);
AppMServ.clonedRA = null;
AppMServ.recordRA = null;
message = "Reset done, now redirect!";
await Task.Delay(100);
// passo a pagina home
NavManager.NavigateTo("Home", true);
}
#endregion Protected Methods
}
}
@@ -0,0 +1,64 @@
@page "/GestCalendario"
<div class="card shadow-lg">
<div class="card-header table-primary d-flex justify-content-between">
<div class="px-0">
<h3>Chiusure aziendali</h3>
</div>
<div class="px-0 d-flex">
<div class="px-1">
@if (ShowAddFes)
{
<div class="input-group mb-3">
<span class="input-group-text">Anno</span>
<input type="number" class="form-control text-end" @bind="@YearReq">
<button class="btn btn-success" @onclick=@AddAllHolidays><i class="fa-solid fa-plus"></i> Aggiungi Festività</button>
</div>
}
@if (ShowAddFer)
{
<div class="input-group mb-3 text-nowrap small">
<span class="input-group-text">Periodo</span>
<input type="date" class="form-control text-end" style="width: 8rem;" @bind="@DtInizio">
<input type="date" class="form-control text-end" style="width: 8rem;" @bind="@DtFine">
<span class="input-group-text">Descr</span>
<input type="text" class="form-control text-end" style="width: 10rem;" @bind="@DescrFerie">
<button class="btn btn-success" @onclick=@AddFerie><i class="fa-solid fa-floppy"></i> Salva</button>
</div>
}
</div>
@if (!ShowAddFer)
{
<div class="px-1">
<button class="btn btn-warning" @onclick=@TglAddFes><i class="fa-solid fa-ellipsis-v"></i> @TxtFes</button>
</div>
}
@if (!ShowAddFes)
{
<div class="px-1">
<button class="btn btn-danger" @onclick=@TglAddFer><i class="fa-solid fa-ellipsis-v"></i> @TxtFer</button>
</div>
}
</div>
</div>
<div class="card-body p-1">
<div class="row">
<div class="col-4">
@if (isLoading)
{
<LoadingData></LoadingData>
}
else
{
<CalAzMan ReportUpdate=ForceReloadCal DtStart="@dtMin" DtEnd="@dtMax"></CalAzMan>
}
</div>
<div class="col-8 ps-0">
<CalendarioAziendale EvDtoList="@SchedEvList" MonthDispl="@numMesi" firstDate="@dtMin" minDate="@dtMin" maxDate="@dtMax" MonthReq="SetMonth" DtReq="SetDate"></CalendarioAziendale>
</div>
</div>
</div>
</div>
@@ -0,0 +1,210 @@
using EgwCoreLib.Utils;
using GPW.CORE.Data.DbModels;
using GPW.CORE.Data.DTO;
using GPW.CORE.Data.Services;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
namespace GPW.CORE.ADM.Components.Pages
{
public partial class GestCalendario
{
#region Protected Fields
protected int anno = DateTime.Today.Year;
protected DateTime dtMax = DateTime.Today.AddYears(1);
protected DateTime dtMin = DateTime.Today;
protected int numMesi = 6;
#endregion Protected Fields
#region Protected Properties
[Inject]
protected MessageService AppMServ { get; set; } = null!;
[Inject]
protected GpwDataService DataService { get; set; } = null!;
[Inject]
protected GpwDataService GDataServ { get; set; } = null!;
protected int idxDipendente
{
get => AppMServ.IdxDipendente;
}
[Inject]
protected IJSRuntime JSRuntime { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected async Task AddAllHolidays()
{
// chiedo verifica
if (!await JSRuntime.InvokeAsync<bool>("confirm", $"Confermi di voler aggiungere tutte le festività dell'anno {YearReq}?"))
return;
isLoading = true;
await InvokeAsync(StateHasChanged);
var elFest = EgwCoreLib.Utils.GestCalendario.ListHolidaysIta(YearReq);
// preparo elenco
foreach (var item in elFest)
{
CalFesteFerieModel currRecord = new CalFesteFerieModel()
{
data = item.When,
codGiust = "FEST",
descrizione = item.What
};
// aggiungo!
await GDataServ.CalFestFerieUpsert(currRecord);
await Task.Delay(5);
}
isLoading = false;
await ReloadData();
}
protected async Task AddFerie()
{
// chiedo verifica
if (!await JSRuntime.InvokeAsync<bool>("confirm", $"Confermi di voler aggiungere Chiusura Aziendale per il periodo {DtInizio:yyyy-MM-dd} - {DtFine:yyyy-MM-dd}?"))
return;
isLoading = true;
await InvokeAsync(StateHasChanged);
int numDays = (int)DtFine.Subtract(DtInizio).TotalDays + 1;
// ciclo x i giorni
for (int i = 0; i < numDays; i++)
{
CalFesteFerieModel currRecord = new CalFesteFerieModel()
{
data = DtInizio.AddDays(i),
codGiust = "FER",
descrizione = DescrFerie
};
// aggiungo!
await GDataServ.CalFestFerieUpsert(currRecord);
await Task.Delay(5);
}
isLoading = false;
await ReloadData();
}
protected override async Task OnInitializedAsync()
{
// recupero mesi da gestire
var monthConf = await DataService.ConfigGetKey("NumMesiCalAzienda");
if (monthConf != null)
{
int intVal = 0;
int.TryParse(monthConf.valore, out intVal);
numMesi = intVal > 0 ? intVal : numMesi;
}
// fix iniziale date... setup periodo (da rivedere in funzione eventi cambio mese dei controlli?!?)
DateTime oggi = DateTime.Today;
dtMin = new DateTime(oggi.Year - 1, 1, 1);
dtMax = dtMin.AddYears(3);
await ReloadData();
}
#endregion Protected Methods
#region Private Fields
private string DescrFerie = "CHIUSURA UFFICIO";
private bool isLoading = false;
private bool ShowAddFer = false;
private bool ShowAddFes = false;
#endregion Private Fields
#region Private Properties
private List<CalFesteFerieModel> ListFermateAzienda { get; set; } = new List<CalFesteFerieModel>();
private List<RegMalattieModel> ListMalattie { get; set; } = new List<RegMalattieModel>();
private List<RegRichiesteModel> ListRichiesteDip { get; set; } = new List<RegRichiesteModel>();
private DateTime DtInizio { get; set; } = DateTime.Today;
private DateTime DtFine { get; set; } = DateTime.Today;
/// <summary>
/// Elenco eventi formato originale (EventDTO)
/// </summary>
private List<EventDTO> SchedEvList { get; set; } = new List<EventDTO>();
private string TxtFer
{
get => ShowAddFer ? "Nascondi Add Chiusure" : "Mostra Add Chiusure";
}
private string TxtFes
{
get => ShowAddFes ? "Nascondi Add Feste" : "Mostra Add Feste";
}
private int YearReq { get; set; } = DateTime.Today.Year;
#endregion Private Properties
#region Private Methods
private async Task ForceReloadCal()
{
await ReloadData();
}
private async Task ReloadData()
{
isLoading = true;
// recupero direttamente da oggetto DB
SchedEvList = await DataService.EventListPeriodo(idxDipendente, dtMin, dtMax);
isLoading = false;
}
private async Task SetDate(DateTime newDate)
{
// se la data fosse esterna all'intervallo considerato...)
if (newDate < dtMin || newDate > dtMax)
{
// verifico se "allargare" alla minima o alla massima
if (newDate < dtMin)
{
dtMin = new DateTime(newDate.Year - 1, 1, 1);
}
else
{
dtMax = new DateTime(newDate.Year + 1, 1, 1);
}
await ReloadData();
}
}
private async Task SetMonth(int newNum)
{
if (numMesi != newNum)
{
numMesi = newNum;
}
await ReloadData();
}
private void TglAddFer()
{
ShowAddFer = !ShowAddFer;
ShowAddFes = false;
}
private void TglAddFes()
{
ShowAddFer = false;
ShowAddFes = !ShowAddFes;
}
#endregion Private Methods
}
}
@@ -0,0 +1,15 @@
@page "/GestOrario"
@inject MessageService AppMServ
@inject AppAuthService AuthServ
<OrarioMan></OrarioMan>
@code {
protected override void OnInitialized()
{
// imposto pagina e info testata
AppMServ.ShowSearch = false;
AppMServ.PageName = AuthServ.Traduci("ManOrarioTipo", AppMServ.UserLang);
AppMServ.PageIcon = AuthServ.Traduci("ManOrarioTipoExpl");
}
}
@@ -0,0 +1,15 @@
@page "/Gruppi"
@inject MessageService AppMServ
@inject AppAuthService AuthServ
<GruppiMan></GruppiMan>
@code {
protected override void OnInitialized()
{
// imposto pagina e info testata
AppMServ.ShowSearch = false;
AppMServ.PageName = AuthServ.Traduci("ManGruppi", AppMServ.UserLang);
AppMServ.PageIcon = AuthServ.Traduci("ManGruppiExpl");
}
}
+56
View File
@@ -0,0 +1,56 @@
@page "/"
@page "/Home"
@page "/Index"
<PageTitle>Home</PageTitle>
<div class="row">
<div class="col-12 col-lg-10 col-xl-8 offset-lg-1 offset-xl-2">
<div class="mt-2 p-4 bg-secondary bg-gradient bg-opacity-25 border border-light rounded shadow">
<div class="row">
<div class="col-6 col-md-8 pr-0">
<h1>GPW</h1>
<div>
@Traduci("GpwPresentationText");
</div>
</div>
<div class="col-6 col-md-4 text-right pl-0">
<div class="d-flex flex-row-reverse">
<div class="px-2 badge rounded-pill bg-dark my-4">
<div class="p-2" style="font-size: 1.5em;">
<a class="text-light" href="https://www.egalware.com/" target="_blank">powered by&nbsp;EgalWare <img width="32" class="img-fluid" src="images/LogoEgw.png" /></a>
</div>
</div>
</div>
</div>
</div>
<div class="row border-dark border-top text-secondary">
<div class="col-12">
<div class="small text-end">GPW Admin - versione Blazor .NET8</div>
</div>
</div>
</div>
<div class="m1-4 py-4">
@if (ListMenu == null || ListMenu.Count == 0)
{
<LoadingData></LoadingData>
}
else
{
<div class="shortcuts">
@foreach (var item in ListMenu)
{
<span class="px-1">
<NavLink class="shortcut rounded-3 text-dark shadow py-3 px-1" href="@item.Url">
<i class="@item.Descript fa-2x"></i>
<span class="shortcut-label">@item.Title</span>
</NavLink>
</span>
}
</div>
}
</div>
</div>
</div>
@@ -0,0 +1,64 @@
using GPW.CORE.Data.DTO;
using GPW.CORE.Data.Services;
using Microsoft.AspNetCore.Components;
namespace GPW.CORE.ADM.Components.Pages
{
public partial class Home : IDisposable
{
#region Public Methods
public void Dispose()
{
AppMServ.EA_MenuUpdated -= AppMServ_EA_MenuUpdated;
}
#endregion Public Methods
#region Protected Properties
[Inject]
protected MessageService AppMServ { get; set; } = null!;
[Inject]
protected AppAuthService AuthServ { get; set; } = null!;
protected List<MenuItemDTO> ListMenu { get; set; } = new List<MenuItemDTO>();
#endregion Protected Properties
#region Protected Methods
protected override void OnInitialized()
{
AppMServ.ShowSearch = false;
AppMServ.PageName = "";
AppMServ.PageIcon = "";
AppMServ.EA_MenuUpdated += AppMServ_EA_MenuUpdated;
ReloadData();
}
protected string Traduci(string lemma)
{
return AuthServ.Traduci(lemma, AppMServ.UserLang);
}
#endregion Protected Methods
#region Private Methods
private void AppMServ_EA_MenuUpdated()
{
ReloadData();
InvokeAsync(StateHasChanged);
}
private void ReloadData()
{
// rilettura menù se mancasse
ListMenu = AppMServ.ListMenu;
}
#endregion Private Methods
}
}
@@ -0,0 +1,26 @@
@page "/Malattia"
<div class="card shadow-lg">
<div class="card-header table-primary d-flex justify-content-between">
<div>
<h3>Certificati Malattia</h3>
</div>
</div>
<div class="card-body p-1">
<div class="row">
<div class="col-4">
@if (isLoading)
{
<LoadingData></LoadingData>
}
else
{
<RegMalattia ReportUpdate=ForceReloadCal DtStart="@dtMin" DtEnd="@dtMax"></RegMalattia>
}
</div>
<div class="col-8 ps-0">
<CalendarioAziendale EvDtoList="@SchedEvList" MonthDispl="@numMesi" firstDate="@dtMin" minDate="@dtMin" maxDate="@dtMax" MonthReq="SetMonth" DtReq="SetDate"></CalendarioAziendale>
</div>
</div>
</div>
</div>
@@ -0,0 +1,124 @@
using GPW.CORE.Data.DbModels;
using GPW.CORE.Data.DTO;
using GPW.CORE.Data.Services;
using Microsoft.AspNetCore.Components;
using static EgwCoreLib.Razor.Toggler;
namespace GPW.CORE.ADM.Components.Pages
{
public partial class Malattia
{
#region Protected Fields
protected int anno = DateTime.Today.Year;
protected DateTime dtMax = DateTime.Today.AddYears(1);
protected DateTime dtMin = DateTime.Today;
protected int numMesi = 6;
#endregion Protected Fields
#region Protected Properties
[Inject]
protected MessageService AppMServ { get; set; } = null!;
[Inject]
protected GpwDataService DataService { get; set; } = null!;
protected int idxDipendente
{
get => AppMServ.IdxDipendente;
}
#endregion Protected Properties
#region Protected Methods
protected override async Task OnInitializedAsync()
{
// recupero mesi da gestire
var monthConf = await DataService.ConfigGetKey("NumMesiCalAzienda");
if (monthConf != null)
{
int intVal = 0;
int.TryParse(monthConf.valore, out intVal);
numMesi = intVal > 0 ? intVal : numMesi;
}
// fix iniziale date... setup periodo (da rivedere in funzione eventi cambio mese dei controlli?!?)
DateTime oggi = DateTime.Today;
dtMin = new DateTime(oggi.Year - 1, 1, 1);
dtMax = dtMin.AddYears(3);
await ReloadData();
}
#endregion Protected Methods
#region Private Fields
private bool isLoading = false;
#endregion Private Fields
#region Private Properties
private List<CalFesteFerieModel> ListFermateAzienda { get; set; } = new List<CalFesteFerieModel>();
private List<RegMalattieModel> ListMalattie { get; set; } = new List<RegMalattieModel>();
private List<RegRichiesteModel> ListRichiesteDip { get; set; } = new List<RegRichiesteModel>();
/// <summary>
/// Elenco eventi formato originale (EventDTO)
/// </summary>
private List<EventDTO> SchedEvList { get; set; } = new List<EventDTO>();
#endregion Private Properties
#region Private Methods
private async Task ForceReloadCal()
{
await ReloadData();
}
private async Task ReloadData()
{
isLoading = true;
// recupero direttamente da oggetto DB
SchedEvList = await DataService.EventListPeriodo(idxDipendente, dtMin, dtMax);
isLoading = false;
}
private async Task SetDate(DateTime newDate)
{
// se la data fosse esterna all'intervallo considerato...)
if (newDate < dtMin || newDate > dtMax)
{
// verifico se "allargare" alla minima o alla massima
if (newDate < dtMin)
{
dtMin = new DateTime(newDate.Year - 1, 1, 1);
}
else
{
dtMax = new DateTime(newDate.Year + 1, 1, 1);
}
await ReloadData();
}
}
private async Task SetMonth(int newNum)
{
if (numMesi != newNum)
{
numMesi = newNum;
}
await ReloadData();
}
#endregion Private Methods
}
}
@@ -0,0 +1,15 @@
@page "/progetti"
@inject MessageService AppMServ
@inject AppAuthService AuthServ
<ProgettiMan></ProgettiMan>
@code {
protected override void OnInitialized()
{
AppMServ.ShowSearch = true;
AppMServ.PageName = AuthServ.Traduci("ManProg", AppMServ.UserLang);
AppMServ.PageIcon = AuthServ.Traduci("ManProgExpl");
}
}
@@ -0,0 +1,7 @@
@page "/ReportProgetti"
<WIP></WIP>
@code {
}
@@ -0,0 +1,16 @@
@page "/ReviewTimbrature"
@inject MessageService AppMServ
@inject AppAuthService AuthServ
<ReviewTimbMan></ReviewTimbMan>
@code {
protected override void OnInitialized()
{
// imposto pagina e info testata
AppMServ.ShowSearch = true;
AppMServ.PageName = AuthServ.Traduci("reviewTimb", AppMServ.UserLang);
AppMServ.PageIcon = AuthServ.Traduci("reviewTimbExpl");
}
}
@@ -0,0 +1,34 @@
@page "/RichiesteDip"
<div class="card shadow-lg">
<div class="card-header table-primary d-flex justify-content-between">
<div>
<h3>Gestione Permessi e Ferie Dipendenti</h3>
</div>
<div>
<Toggler SelFilter="@ToggleData" FilterChanged="evToggled"></Toggler>
</div>
</div>
<div class="card-body p-1">
<div class="row">
<div class="col-4">
@if (isLoading)
{
<LoadingData></LoadingData>
}
else
{
<RegRichieste ReportUpdate=ForceReloadCal months="@numMesi" ShowNeedConf=@OnlyNeedConf></RegRichieste>
}
</div>
<div class="col-8 ps-0">
<CalendarioAziendale EvDtoList="@SchedEvList" MonthDispl="@numMesi" firstDate="@dtMin" minDate="@dtMin" maxDate="@dtMax" MonthReq="SetMonth" DtReq="SetDate" ShowNeedConf="@OnlyNeedConf"></CalendarioAziendale>
</div>
</div>
</div>
</div>
@@ -0,0 +1,146 @@
using GPW.CORE.Data.DbModels;
using GPW.CORE.Data.DTO;
using GPW.CORE.Data.Services;
using Microsoft.AspNetCore.Components;
using static EgwCoreLib.Razor.Toggler;
namespace GPW.CORE.ADM.Components.Pages
{
public partial class RichiesteDip
{
#region Protected Fields
protected int anno = DateTime.Today.Year;
protected DateTime dtMax = DateTime.Today.AddYears(1);
protected DateTime dtMin = DateTime.Today;
protected int numMesi = 6;
#endregion Protected Fields
#region Protected Properties
[Inject]
protected MessageService AppMServ { get; set; } = null!;
[Inject]
protected GpwDataService DataService { get; set; } = null!;
protected int idxDipendente
{
get => AppMServ.IdxDipendente;
}
#endregion Protected Properties
#region Protected Methods
protected override async Task OnInitializedAsync()
{
initToggler();
// recupero mesi da gestire
var monthConf = await DataService.ConfigGetKey("NumMesiCalAzienda");
if (monthConf != null)
{
int intVal = 0;
int.TryParse(monthConf.valore, out intVal);
numMesi = intVal > 0 ? intVal : numMesi;
}
// fix iniziale date... setup periodo (da rivedere in funzione eventi cambio mese dei controlli?!?)
DateTime oggi = DateTime.Today;
dtMin = new DateTime(oggi.Year - 1, 1, 1);
dtMax = dtMin.AddYears(3);
await ReloadData();
}
#endregion Protected Methods
#region Private Fields
private bool isLoading = false;
#endregion Private Fields
#region Private Properties
private List<CalFesteFerieModel> ListFermateAzienda { get; set; } = new List<CalFesteFerieModel>();
private List<RegMalattieModel> ListMalattie { get; set; } = new List<RegMalattieModel>();
private List<RegRichiesteModel> ListRichiesteDip { get; set; } = new List<RegRichiesteModel>();
private bool OnlyNeedConf { get; set; } = false;
/// <summary>
/// Elenco eventi formato originale (EventDTO)
/// </summary>
private List<EventDTO> SchedEvList { get; set; } = new List<EventDTO>();
private SelectGlobalToggle ToggleData { get; set; } = new SelectGlobalToggle();
#endregion Private Properties
#region Private Methods
private async Task evToggled(SelectGlobalToggle newTogData)
{
ToggleData = newTogData;
OnlyNeedConf = !ToggleData.isActive;
await Task.Delay(1);
}
private async Task ForceReloadCal()
{
await ReloadData();
}
private void initToggler()
{
ToggleData = new SelectGlobalToggle()
{
leftString = "Da approvare",
rightString = "Tutti",
placardCss = "bg-light border-light text-dark",
};
}
private async Task ReloadData()
{
isLoading = true;
// recupero direttamente da oggetto DB
SchedEvList = await DataService.EventListPeriodo(idxDipendente, dtMin, dtMax);
isLoading = false;
}
private async Task SetDate(DateTime newDate)
{
// se la data fosse esterna all'intervallo considerato...)
if (newDate < dtMin || newDate > dtMax)
{
// verifico se "allargare" alla minima o alla massima
if (newDate < dtMin)
{
dtMin = new DateTime(newDate.Year - 1, 1, 1);
}
else
{
dtMax = new DateTime(newDate.Year + 1, 1, 1);
}
await ReloadData();
}
}
private async Task SetMonth(int newNum)
{
if (numMesi != newNum)
{
numMesi = newNum;
}
await ReloadData();
}
#endregion Private Methods
}
}
@@ -0,0 +1,14 @@
@page "/spostaFasi"
@inject MessageService AppMServ
@inject AppAuthService AuthServ
<SpostaFasiMan></SpostaFasiMan>
@code {
protected override void OnInitialized()
{
AppMServ.ShowSearch = true;
AppMServ.PageName = AuthServ.Traduci("SpostaFasi", AppMServ.UserLang);
AppMServ.PageIcon = AuthServ.Traduci("SpostaFasiExpl");
}
}
@@ -0,0 +1,7 @@
 @page "/SpostaOre"
<WIP></WIP>
@code {
}
@@ -0,0 +1,15 @@
@page "/TagMensili"
@inject MessageService AppMServ
@inject AppAuthService AuthServ
<MonthTagMan></MonthTagMan>
@code {
protected override void OnInitialized()
{
// imposto pagina e info testata
AppMServ.ShowSearch = false;
AppMServ.PageName = AuthServ.Traduci("tagMensili", AppMServ.UserLang);
AppMServ.PageIcon = AuthServ.Traduci("tagMensiliExpl");
}
}
+17
View File
@@ -0,0 +1,17 @@
@page "/tags"
@inject MessageService AppMServ
@inject AppAuthService AuthServ
<TagsMan></TagsMan>
@code {
protected override void OnInitialized()
{
// imposto pagina e info testata
AppMServ.ShowSearch = true;
AppMServ.PageName = AuthServ.Traduci("ManTags", AppMServ.UserLang);
AppMServ.PageIcon = AuthServ.Traduci("ManTagsExpl");
}
}
@@ -0,0 +1,7 @@
@page "/TimbratureMensili"
<WIP></WIP>
@code {
}
+8
View File
@@ -0,0 +1,8 @@
<CascadingAuthenticationState>
<Router AppAssembly="typeof(Program).Assembly">
<Found Context="routeData">
<RouteView RouteData="routeData" DefaultLayout="typeof(Layout.MainLayout)" />
<FocusOnNavigate RouteData="routeData" Selector="h1" />
</Found>
</Router>
</CascadingAuthenticationState>
+21
View File
@@ -0,0 +1,21 @@
@using System.Net.Http
@using System.Net.Http.Json
@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 static Microsoft.AspNetCore.Components.Web.RenderMode
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.JSInterop
@using GPW.CORE.ADM
@using GPW.CORE.ADM.Components
@using GPW.CORE.ADM.Components.Compo
@using GPW.CORE.ADM.Components.Pages
@using GPW.CORE.Data
@using GPW.CORE.Data.DbModels
@using GPW.CORE.Data.DTO
@using GPW.CORE.Data.Services
@using EgwCoreLib.Razor
@using Radzen
@using Radzen.Blazor
+77
View File
@@ -0,0 +1,77 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<Version>4.1.2502.0418</Version>
</PropertyGroup>
<ItemGroup>
<Content Remove="compilerconfig.json" />
</ItemGroup>
<ItemGroup>
<_WebToolingArtifacts Remove="Properties\PublishProfiles\IIS-PROD.pubxml" />
<_WebToolingArtifacts Remove="Properties\PublishProfiles\IIS01.pubxml" />
<_WebToolingArtifacts Remove="Properties\PublishProfiles\IIS02.pubxml" />
<_WebToolingArtifacts Remove="Properties\PublishProfiles\IIS03.pubxml" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\GPW.CORE.Data\GPW.CORE.Data.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Data\" />
</ItemGroup>
<ItemGroup>
<None Include="compilerconfig.json" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Azure.Identity" Version="1.11.4" />
<PackageReference Include="Blazored.FluentValidation" Version="2.2.0" />
<PackageReference Include="EgwCoreLib.Razor" Version="1.5.2501.1716" />
<PackageReference Include="EgwCoreLib.Utils" Version="1.5.2501.1716" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.Negotiate" Version="8.0.8" />
<PackageReference Include="Microsoft.Web.LibraryManager.Build" Version="2.1.175" />
<PackageReference Include="NLog" Version="5.4.0" />
<PackageReference Include="NLog.Web.AspNetCore" Version="5.4.0" />
<PackageReference Include="Radzen.Blazor" Version="5.9.7" />
<PackageReference Include="System.Text.Json" Version="9.0.0" />
</ItemGroup>
<ItemGroup>
<Content Update="wwwroot\app.css">
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Update="wwwroot\favicon.ico">
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Update="wwwroot\favicon.png">
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Update="wwwroot\manifest.json">
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<None Update="logs\.placeholder">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="temp\.placeholder">
<CopyToOutputDirectory>PreserveNewest</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>
+145
View File
@@ -0,0 +1,145 @@
using Blazored.LocalStorage;
using Blazored.SessionStorage;
using GPW.CORE.ADM.Components;
using GPW.CORE.Data;
using GPW.CORE.Data.Services;
using Microsoft.AspNetCore.Authentication.Negotiate;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.AspNetCore.Localization;
using Microsoft.Extensions.FileProviders;
using NLog;
using NLog.Web;
using Radzen;
using StackExchange.Redis;
using System.Globalization;
var builder = WebApplication.CreateBuilder(args);
var logger = LogManager.Setup()
.LoadConfigurationFromAppSettings()
.GetCurrentClassLogger();
logger.Info("Program.cs: startup");
// 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;
});
logger.Info("Add Auth");
ConfigurationManager configuration = builder.Configuration;
// REDIS setup
logger.Info("Setup REDIS");
string connStringRedis = configuration.GetConnectionString("Redis") ?? "localhost:6379,DefaultDatabase=15";
string redisSrvAddr = connStringRedis.Substring(0, connStringRedis.IndexOf(":"));
// avvio oggetto shared x redis...
var redisMultiplexer = ConnectionMultiplexer.Connect(connStringRedis);
builder.Services.AddSingleton<IConnectionMultiplexer>(redisMultiplexer);
builder.Services.AddSingleton<LicenseService>();
builder.Services.AddSingleton<GpwDataService>();
builder.Services.AddSingleton<AppAuthService>();
builder.Services.AddScoped<MessageService>();
builder.Services.AddBlazoredLocalStorage();
builder.Services.AddBlazoredSessionStorage();
// Add services to the container.
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
// abilitazione x email management con MailKit
builder.Services.AddTransient<IEmailSender, MailKitEmailSender>();
builder.Services.Configure<MailKitEmailSenderOptions>(options =>
{
options.Host_Address = configuration["ExternalProviders:MailKit:SMTP:Address"]!;
options.Host_Port = Convert.ToInt32(configuration["ExternalProviders:MailKit:SMTP:Port"]);
options.Host_Username = configuration["ExternalProviders:MailKit:SMTP:Account"]!;
options.Host_Password = configuration["ExternalProviders:MailKit:SMTP:Password"]!;
options.Sender_EMail = configuration["ExternalProviders:MailKit:SMTP:SenderEmail"]!;
options.Sender_Name = configuration["ExternalProviders:MailKit:SMTP:SenderName"]!;
});
builder.Services.AddHttpContextAccessor();
// aggiunto compressione
builder.Services.AddResponseCompression(options =>
{
options.EnableForHttps = true;
});
// aggiunta componenti Radzen
builder.Services.AddRadzenComponents();
var app = builder.Build();
// aggiunt base URL x routing corretto
app.UsePathBase(configuration.GetValue<string>("ServerConf:BaseUrl"));
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseResponseCompression();
app.UseExceptionHandler("/Error", createScopeForErrors: true);
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
// cultura IT...
var supportedCultures = new[]{
new CultureInfo("it-IT")
};
app.UseRequestLocalization(new RequestLocalizationOptions
{
DefaultRequestCulture = new RequestCulture("it-IT"),
SupportedCultures = supportedCultures,
FallBackToParentCultures = false
});
CultureInfo.DefaultThreadCurrentCulture = CultureInfo.CreateSpecificCulture("it-IT");
app.UseHttpsRedirection();
app.UseStaticFiles();
// gestione static files: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/static-files?view=aspnetcore-8.0
string pathExport = configuration.GetValue<string>("ServerConf:BasePathExport") ?? configuration.GetValue<string>("OptConf:BasePathExport") ?? "";
if (!string.IsNullOrEmpty(pathExport))
{
// se non esistesse creo...
if(!Directory.Exists(pathExport))
{
Directory.CreateDirectory(pathExport);
logger.Info($"Creata dir export: {pathExport}");
}
// verifico esista folder disegni
if (Directory.Exists(pathExport))
{
// gestione cartella x PDF
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(pathExport),
RequestPath = "/export",
});
}
}
logger.Info("Add disegni path");
app.UseAntiforgery();
app.UseAuthentication();
app.UseAuthorization();
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode();
logger.Info("Run App");
app.Run();
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is used by the publish/package process of your Web project. You can customize the behavior of this process
by editing this MSBuild file. In order to learn more about this please visit https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>MSDeploy</WebPublishMethod>
<LaunchSiteAfterPublish>true</LaunchSiteAfterPublish>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish>https://office.egalware.com/GPW/CORE.ADM8/</SiteUrlToLaunchAfterPublish>
<ExcludeApp_Data>false</ExcludeApp_Data>
<ProjectGuid>e4229ee4-ed4f-4507-8058-b01dc3ca1b28</ProjectGuid>
<SelfContained>false</SelfContained>
<MSDeployServiceURL>https://office.egalware.com:8172/MsDeploy.axd</MSDeployServiceURL>
<DeployIisAppPath>office.egalware.com/GPW/CORE.ADM8</DeployIisAppPath>
<RemoteSitePhysicalPath />
<SkipExtraFilesOnServer>true</SkipExtraFilesOnServer>
<MSDeployPublishMethod>WMSVC</MSDeployPublishMethod>
<EnableMSDeployBackup>true</EnableMSDeployBackup>
<EnableMsDeployAppOffline>true</EnableMsDeployAppOffline>
<UserName>jenkins</UserName>
<_SavePWD>true</_SavePWD>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
</Project>

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