Compare commits
794 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3e0dbd22a4 | |||
| d7757cf0db | |||
| 03db156f99 | |||
| 15be702f29 | |||
| ababa059e9 | |||
| f14f92d73f | |||
| a3e3c14ee7 | |||
| 47247090d8 | |||
| 2c38306ab5 | |||
| 76a91c283d | |||
| 44797c7b51 | |||
| 815952e575 | |||
| 803f75ac9b | |||
| 6a78203b97 | |||
| 7b20cb3b3d | |||
| 1f934d579c | |||
| 1db1024020 | |||
| 4097c701d0 | |||
| f3d7d49e87 | |||
| cdd1a1a29f | |||
| f5eda3686d | |||
| 38401093df | |||
| ff75bc3d68 | |||
| ac5c8b3880 | |||
| b072312a71 | |||
| f6b6174ab3 | |||
| d74b92db7d | |||
| 841c8ddc26 | |||
| 9a248d5219 | |||
| 5d319b750b | |||
| 8b2679b878 | |||
| 404b49bb4d | |||
| 1ab60db8fe | |||
| 541ef293cc | |||
| 1cf9bc3335 | |||
| f853a96179 | |||
| ea223b57b9 | |||
| 7147fd0cb7 | |||
| fa845a823f | |||
| 6bcea21059 | |||
| b910b8439c | |||
| 2b0d24421c | |||
| 328ce7dd48 | |||
| 1f6af30daf | |||
| 5b1e04ae48 | |||
| 30b9c7e662 | |||
| 2867b1a5d9 | |||
| d30d5d1d0a | |||
| cec0ab3fc8 | |||
| abdfd82b0a | |||
| 08c746feb6 | |||
| 53fa89e571 | |||
| db8d92cd96 | |||
| 6bff05f8d4 | |||
| 4842e8d81f | |||
| 4ddb77bcaf | |||
| 578477040f | |||
| 9edcc17479 | |||
| abb64f1565 | |||
| 7a3696bf3c | |||
| 86015d13ae | |||
| 2812bb6aea | |||
| 06d9d00975 | |||
| 897432d994 | |||
| dca3ad5847 | |||
| 95fa52a3ff | |||
| 0e1e95d77a | |||
| b7bd4d72ec | |||
| 230c6a3efc | |||
| b1afa82a91 | |||
| a8ec6f6e0f | |||
| 565c20e396 | |||
| adaa2657be | |||
| 978b1837fe | |||
| bc58630463 | |||
| 94245a0a44 | |||
| b25ddf87b1 | |||
| 3c106a4e5d | |||
| 807920341b | |||
| 3173393e8d | |||
| 6a86c235cc | |||
| 80b058d524 | |||
| bb4a3ce94d | |||
| de1ff13988 | |||
| e1342d08c2 | |||
| da9300cd6b | |||
| f2fcbb2f75 | |||
| 25eb7f1dc3 | |||
| 109a16070f | |||
| 5722ad4167 | |||
| ddcca0583a | |||
| 77476cea54 | |||
| 378a82074d | |||
| 2ab73d94f3 | |||
| 9193237995 | |||
| 27687a85cf | |||
| 045e8e5363 | |||
| 7251a81794 | |||
| 29bebbdd7b | |||
| d01bfa97b1 | |||
| 9089dfea44 | |||
| 5b62ae2b55 | |||
| 0ba78dbd4e | |||
| 2e91431129 | |||
| d805de405b | |||
| 6b6d47d71b | |||
| 77cb1efc2a | |||
| 08656c7404 | |||
| 3e902c72fe | |||
| bc70a085c3 | |||
| 848b6537d2 | |||
| 55473e9081 | |||
| a881ae9079 | |||
| f4f2b7c857 | |||
| 3d6e818b8d | |||
| ec48ab08b0 | |||
| d5a2406704 | |||
| 2044515ce4 | |||
| 3000a43330 | |||
| 61fafe9236 | |||
| 3879bcc6f3 | |||
| b678109ec0 | |||
| 67a3f582bf | |||
| 0d08c57112 | |||
| a62d1688b1 | |||
| d3ef9ce45f | |||
| 46f3146d85 | |||
| 22c9e1186c | |||
| e60dc2e172 | |||
| 14bcf025e0 | |||
| 0713f3d52d | |||
| 10ce6709dc | |||
| b415cb6b53 | |||
| 1ccfd55a1c | |||
| bcea43806b | |||
| e1de4d2bde | |||
| 5f7ce2ee5c | |||
| 1b1855c8f4 | |||
| 0aafcc6770 | |||
| f947f98e39 | |||
| 3ba140305e | |||
| dcae718f75 | |||
| 921cbed53b | |||
| dc43f4fe18 | |||
| 76f7c0d05c | |||
| 4adda8deaf | |||
| 236858e4dd | |||
| 2367b25c3c | |||
| 840b27e452 | |||
| 09cb7fd30c | |||
| c53452bf98 | |||
| fd99bf78dd | |||
| 9c0aa41620 | |||
| 01647b74b4 | |||
| 573c967670 | |||
| 0c2b819fb3 | |||
| 1e0d2746c6 | |||
| 60ed02f452 | |||
| 0cbea6a055 | |||
| 0302aee0e8 | |||
| ba96677c80 | |||
| fe42629e0e | |||
| e2627ffb8d | |||
| 955ee08a45 | |||
| c0c3bd65e9 | |||
| c5a0d1595b | |||
| d53a89b95e | |||
| 212b6abfef | |||
| ed249951e2 | |||
| 9601eaffcd | |||
| d8db7a8075 | |||
| 7928ff14e2 | |||
| a13bea1813 | |||
| ebd5af2d77 | |||
| 4fd374a4c3 | |||
| a59bb18c0e | |||
| 3e2729f594 | |||
| 4f33831180 | |||
| 23f334d233 | |||
| c21532256d | |||
| 0d4fb29b5b | |||
| 10a1356a6e | |||
| bf27ae8e19 | |||
| 041eae2260 | |||
| c3f011ec75 | |||
| 9d05a9f068 | |||
| 5b459bbd7b | |||
| 05ef3a3a4f | |||
| f1b5c99463 | |||
| 2f7337348e | |||
| 7f88624935 | |||
| dacd3b9bcd | |||
| 596449f259 | |||
| e149445529 | |||
| 178d7a3ef0 | |||
| 53d505006a | |||
| 53e1abd2c0 | |||
| 321b7a3a6f | |||
| 2e54c8b164 | |||
| 8c978f68c2 | |||
| 781c570a3d | |||
| de2a8cb6a5 | |||
| 63e92f0c83 | |||
| 73a28e33b4 | |||
| f4d2265de2 | |||
| b40764c2bc | |||
| 0333154935 | |||
| fc19fb563e | |||
| fd6a0512ba | |||
| 7c4ae1f7dc | |||
| b9c2418532 | |||
| 50a6848f25 | |||
| 6e1b60cc71 | |||
| 23a3985251 | |||
| 274d58ab68 | |||
| 14637860e0 | |||
| fe0545084a | |||
| e37b5050e2 | |||
| fc3a6a70da | |||
| 9837f276d7 | |||
| 865aa0afab | |||
| ef2bd7c5d5 | |||
| 3c92333f0e | |||
| 190b7a10b7 | |||
| 7a89709a29 | |||
| 3777090416 | |||
| 16d13748c9 | |||
| 5a46df0f19 | |||
| d3ff540382 | |||
| 15fcbd57b9 | |||
| 07ac5aa9a5 | |||
| 488ca47e50 | |||
| b8af310248 | |||
| dbfc7fddc4 | |||
| e6196db490 | |||
| 00e4a0158e | |||
| 838e0f6957 | |||
| b955c6e38e | |||
| 51eb178934 | |||
| bd6ef3d0ae | |||
| 6e13ebe8a9 | |||
| 25656f5eec | |||
| bc260f5de5 | |||
| 26507ae5bf | |||
| f3fb081103 | |||
| 3930a9e8dc | |||
| 09d1f42934 | |||
| 394d924d1e | |||
| d2ad286f0f | |||
| 4e1e958db0 | |||
| de09175f28 | |||
| 2d009a76d8 | |||
| 533452776d | |||
| 209fe7aa6c | |||
| da214155c0 | |||
| d36b60dc17 | |||
| 8527b91e6c | |||
| d345e84279 | |||
| 8bf47bb03b | |||
| f1068e3f42 | |||
| c9c69f535a | |||
| baecdd9c32 | |||
| 56f0d36570 | |||
| aa7ef25da9 | |||
| 75340443a2 | |||
| 1eafdee5af | |||
| f9ea6f5721 | |||
| 3e363588e7 | |||
| 94d2d46919 | |||
| e6065535b4 | |||
| 26110c9885 | |||
| 38a9d7be73 | |||
| b69ca54dcc | |||
| bd1c955f72 | |||
| a4947a95cd | |||
| 4b7f560e5a | |||
| 69174bdb71 | |||
| f10fbffaf5 | |||
| 8c5fa25801 | |||
| e53daaf6a7 | |||
| 6e44e7cb56 | |||
| e2dccac335 | |||
| 27876c6530 | |||
| 4c10c121e3 | |||
| 0300ce6eac | |||
| 28ce9a3a1c | |||
| fc9cb8d67a | |||
| 7d9d3ccbef | |||
| 1dd4b4ae30 | |||
| a5646aeabb | |||
| 00ed8fbf17 | |||
| 1948fee63a | |||
| ba0c0af831 | |||
| d2504e4fb6 | |||
| 5c674bf62d | |||
| 7425be3e2a | |||
| 8cd48454a1 | |||
| f35edfb9db | |||
| 402442b8d2 | |||
| 10465fc7f3 | |||
| 9a87d67b3d | |||
| 473ce70f9a | |||
| 417fbe31c1 | |||
| 07e4ee2de1 | |||
| 34db49f776 | |||
| d7239dbf85 | |||
| 0ad217bc54 | |||
| 9f23e69505 | |||
| 58df987e47 | |||
| ae615bf8d6 | |||
| 6e956330ea | |||
| b75f501290 | |||
| 69c8b7c97a | |||
| 09a988ede9 | |||
| 63943fa46d | |||
| 762129bdd4 | |||
| 3cf826c048 | |||
| aa0b0f92e4 | |||
| 10fc218d8b | |||
| a700a8752c | |||
| 105cf4b756 | |||
| d46a0b731e | |||
| b0df9f97b4 | |||
| 46c8023ab4 | |||
| 93c1b3b189 | |||
| 9e66214f66 | |||
| a4df2bba0d | |||
| 705f2efd10 | |||
| 22f49241e4 | |||
| c043486f82 | |||
| 5c30b30a27 | |||
| 3dc74caa98 | |||
| 384db1cdd0 | |||
| 62b6c3a04d | |||
| fa716e9f2f | |||
| 476487b3c0 | |||
| 8899289d29 | |||
| d8a0f5c453 | |||
| 4434cff466 | |||
| 87c42e0910 | |||
| 34df9c59fb | |||
| 1daeb227ea | |||
| cac3f95895 | |||
| 6a169705e6 | |||
| 584177e5c6 | |||
| 44ca4a4fd6 | |||
| ead97b6863 | |||
| 5806f0619e | |||
| 204ecb47b7 | |||
| 388aa0cd65 | |||
| f10c0d19c7 | |||
| 9f105dd244 | |||
| 59e2622e58 | |||
| 614ebcf818 | |||
| b428ef59da | |||
| b4d2218f79 | |||
| ad6d4e9875 | |||
| 6530664616 | |||
| ba0dc30c42 | |||
| 8d9f106a9a | |||
| f408c0e9d6 | |||
| 81ad753268 | |||
| ed6bfd3b05 | |||
| 2b7346063a | |||
| fa33bc9753 | |||
| fff73423c2 | |||
| 0d159e76cc | |||
| 7e7393f42c | |||
| 1d8a64fb2a | |||
| c766ffeda3 | |||
| 86ded42bae | |||
| 9c6733546f | |||
| 201e092b21 | |||
| be122e6845 | |||
| 512494aa38 | |||
| 1eb2d54235 | |||
| de556ab2a8 | |||
| 564a87e177 | |||
| 140711eb39 | |||
| eb280b9556 | |||
| 5341eae5ca | |||
| 2cd3882808 | |||
| 10819e97f0 | |||
| 3ed1921d3d | |||
| 9ae0daa69e | |||
| f776112e5b | |||
| de9fc59637 | |||
| 5e75d12a79 | |||
| 2fab9ede6e | |||
| 7e1d1e464c | |||
| d548f0537c | |||
| b91b473dbe | |||
| 98a3f50771 | |||
| 551991bc95 | |||
| e561ccb2a7 | |||
| 9f3eb7dde0 | |||
| 2a31fb9dcf | |||
| bdaaefb076 | |||
| 74cde6035f | |||
| 2507a9e35e | |||
| d37766b3a3 | |||
| 3de47b92f2 | |||
| 81f9f4971e | |||
| 7e3fc3e8f5 | |||
| 1e0486e7b5 | |||
| be357ff225 | |||
| 8fff35405a | |||
| f7b482d36c | |||
| a719be6195 | |||
| efeca5935d | |||
| 6510fce274 | |||
| a0f30be0e3 | |||
| 91a956ae60 | |||
| 9d62995a70 | |||
| 8b85b4a2f8 | |||
| 619932b4c1 | |||
| b8429b1867 | |||
| 88a260e88f | |||
| 3dd5843ee5 | |||
| fd210e82d7 | |||
| 195ed3c157 | |||
| fb72e45e44 | |||
| 4c1d7d7056 | |||
| d6b8d47dc7 | |||
| 157fc77650 | |||
| acd88fd0a4 | |||
| c2523ff0bc | |||
| c5d897919d | |||
| 03ede3a967 | |||
| 19f34abbec | |||
| 8b20f36c1b | |||
| 262d237f12 | |||
| 3781031973 | |||
| ce2e409704 | |||
| 8fa92198f9 | |||
| 6a446c03e3 | |||
| 81c7008771 | |||
| b1a8db2882 | |||
| f64a7d3f3d | |||
| 1580c939dd | |||
| 899903aa5b | |||
| 8516049343 | |||
| 7a13e99d69 | |||
| f0d5c2a94a | |||
| ec37691dff | |||
| 7c2033d1de | |||
| 8f403c0dee | |||
| 88b7f4b9b9 | |||
| a45d6bcf6b | |||
| a115517dde | |||
| 26c21e48b3 | |||
| fc83cbf7ec | |||
| 94837e953e | |||
| 47a655c820 | |||
| 7fa1dbce3b | |||
| f16541a066 | |||
| f69c70b3b7 | |||
| 4a1fbe591e | |||
| 15a0bd295c | |||
| af3d49cf4e | |||
| 9b90a1b3ca | |||
| 3feea9e514 | |||
| ce5d50209e | |||
| 9e7c7dea40 | |||
| 3476cd79a4 | |||
| 6f7f676b01 | |||
| c3ea2126aa | |||
| 591aada1e0 | |||
| 98df74fa0d | |||
| 8dfdb68a6a | |||
| 8f08d6457c | |||
| 9b96f7134b | |||
| 520eb04d30 | |||
| cc308c05df | |||
| 6ee87f4bce | |||
| 131fb6ae15 | |||
| a78609b96d | |||
| fbd70decf5 | |||
| 84e4c086f4 | |||
| 5b695ea7c5 | |||
| f2befdd90d | |||
| eaf63a3c72 | |||
| 348cb21b0a | |||
| 137f8d601f | |||
| 9cc350da0c | |||
| 40e666fa1b | |||
| c129b9640c | |||
| af65a73e27 | |||
| c1d1c9746c | |||
| dd8e5272a3 | |||
| 65b22cbc65 | |||
| 5f859bb317 | |||
| 60fd732a8c | |||
| f345d804ab | |||
| f2e1d867e9 | |||
| 1789e9f40a | |||
| 537793cb8f | |||
| a750376dba | |||
| a9798bd366 | |||
| fc430a40af | |||
| 16e3a2d992 | |||
| 64701ff758 | |||
| ba89ff0726 | |||
| 708a907c05 | |||
| c18ebd0f89 | |||
| 8ff9385b67 | |||
| eb6652699a | |||
| 220aaf21c0 | |||
| 19beb952bb | |||
| 9a4bc648ee | |||
| 085540092a | |||
| 5e45bd2a69 | |||
| e48481bdc0 | |||
| 4428eed168 | |||
| 892603b956 | |||
| 4c9b662e4c | |||
| 7a6f08343c | |||
| 11ddd5ae79 | |||
| 1fb4795549 | |||
| 818396c6d8 | |||
| a3146a61cf | |||
| bda16699ab | |||
| 21b32386d7 | |||
| de448e95fc | |||
| 18d20707c0 | |||
| cc60712fd2 | |||
| aa236cfb5c | |||
| 44125ad79d | |||
| 5a751ff4af | |||
| fe2d31cfc5 | |||
| fa55eba725 | |||
| 18d48ecaae | |||
| 5c9098e072 | |||
| a01153771b | |||
| eae9f8f287 | |||
| 1a8753abea | |||
| fb413892a3 | |||
| 59560f927a | |||
| b1c02d1483 | |||
| d77d1603bc | |||
| 6b70c4be1d | |||
| f3fa19f96c | |||
| 13c09b4341 | |||
| 26cf47f6c7 | |||
| 8e79305eac | |||
| d88b0fac6f | |||
| 8d3a69afc1 | |||
| b00f5f26a6 | |||
| 492d6fa9f4 | |||
| df3f5e5625 | |||
| 2b48f19f92 | |||
| 223607f649 | |||
| 226459c819 | |||
| c50452f441 | |||
| 7cb2ad724c | |||
| 742bda00c1 | |||
| b8073b5a73 | |||
| 5be8e2735e | |||
| 6458f63c4a | |||
| 1c9d19daf9 | |||
| f332efba77 | |||
| 74b4c06f75 | |||
| 605c68d3d5 | |||
| 5166c4bc5e | |||
| 54d9dade4b | |||
| 83ab057286 | |||
| a197d61ddb | |||
| 074eaf343d | |||
| d85ede57c1 | |||
| 1162160350 | |||
| e72e975754 | |||
| 5cfc4bb865 | |||
| 5dcbe3ed46 | |||
| 3e2160d64d | |||
| e417edf727 | |||
| 3b862aa03f | |||
| 09581bd653 | |||
| 44acbb9360 | |||
| 3bffd2b78c | |||
| 52c73973e6 | |||
| 80e4590abe | |||
| b1d0bbf780 | |||
| 8051a1adb3 | |||
| b4562b6c83 | |||
| 80febcc6cb | |||
| 18b4c113d1 | |||
| 1a324a1cd9 | |||
| f4e02e6f6f | |||
| 11702db3e5 | |||
| b8d4bd1a65 | |||
| 26a97ed6ec | |||
| c33927fd93 | |||
| f73891da9e | |||
| 9a2f0a2fb8 | |||
| 59092a472b | |||
| 3d24578a3b | |||
| ff0b84042c | |||
| b43d849f3e | |||
| 9b382867f6 | |||
| e694553f89 | |||
| ce30ca1eba | |||
| b604046a2c | |||
| 7713465e00 | |||
| b549ef07a4 | |||
| 206f5e9bc4 | |||
| a6b8eeff5d | |||
| ee36394b3d | |||
| 3dd6ac1018 | |||
| 5a62abbdb0 | |||
| 6cb0544754 | |||
| a83ff37995 | |||
| 259679c178 | |||
| ce176cd47e | |||
| a781bbf6ff | |||
| 84d40f830c | |||
| 4902065f0a | |||
| ccc02a48b3 | |||
| f5c764eafb | |||
| a9ac7f284f | |||
| baa6a84ad5 | |||
| e2778a51ec | |||
| a0c831af95 | |||
| 37ae849c93 | |||
| 062b3fa556 | |||
| cea53a124c | |||
| 796679f91b | |||
| bf9241aacb | |||
| a18011e45d | |||
| a2154c0b84 | |||
| 5f06c38bf5 | |||
| 4307e6fe42 | |||
| ad8fbf4852 | |||
| 0e71534de7 | |||
| 3705bf6e5f | |||
| 6a4dff3386 | |||
| 41f65df85d | |||
| c460b5fb77 | |||
| 88ab08e4b8 | |||
| e39e62e4cc | |||
| 495885a2be | |||
| ac26e1fc37 | |||
| 9c089aad42 | |||
| 9843c061e6 | |||
| df91add2f3 | |||
| 96c430abd3 | |||
| 23caf99c91 | |||
| 3f94ad59de | |||
| 28296cb22a | |||
| f482e53a84 | |||
| 821b82d242 | |||
| 235a074147 | |||
| 9781967c4a | |||
| 6789a29661 | |||
| 1afd110487 | |||
| 22e2141cf3 | |||
| 896d2fbb12 | |||
| 2dc27d3917 | |||
| 231fb1209b | |||
| 5d31b10f75 | |||
| eb37fa4d0d | |||
| 35d7fea84b | |||
| 319680a974 | |||
| dfa0806326 | |||
| 5d635662c8 | |||
| 1b88196574 | |||
| 8fd0c430f9 | |||
| b8ea6f5c7a | |||
| f82e8a6506 | |||
| e4d3726203 | |||
| ffffb7ce63 | |||
| 9eed839919 | |||
| f523b19968 | |||
| 41de920ac3 | |||
| df00a96295 | |||
| d53ec5e37c | |||
| 90683eb2ca | |||
| ca49ba4065 | |||
| 5a24e4f6b4 | |||
| 100a0ee759 | |||
| f09f8ab566 | |||
| 825622144e | |||
| 8e6e3b55f4 | |||
| bda4ea12a2 | |||
| b408719b53 | |||
| a8147d257c | |||
| 347aa867c0 | |||
| 5c670365ec | |||
| 7c74090eb3 | |||
| 1a90e4b729 | |||
| f88e5e3d07 | |||
| 2a0c8d09d4 | |||
| f13e712470 | |||
| e7d100e7d3 | |||
| 0973c677a1 | |||
| 9b91c95369 | |||
| 15c2733e0e | |||
| 19a015e072 | |||
| e77c7b3c7f | |||
| 882ca626de | |||
| 4c87399a32 | |||
| b18820ce02 | |||
| d91455492e | |||
| 9357519813 | |||
| 23886b4109 | |||
| 44f9414f0d | |||
| 18865fa274 | |||
| a65b47623d | |||
| 0df42a5dce | |||
| 0ebd0133c9 | |||
| 34471c6073 | |||
| 405d73c3c7 | |||
| 932e9a75dd | |||
| a28c0fbac5 | |||
| 982aace898 | |||
| 9faefb3746 | |||
| 31c17016bd | |||
| 6882f43733 | |||
| 812023ae42 | |||
| 515ee06c00 | |||
| 60c1de1e38 | |||
| fcc13c4fba | |||
| 50b8753a1a | |||
| 9c8ec35bfd | |||
| e2508984a2 | |||
| 282c03abcc | |||
| 81466594c8 | |||
| cc8495f211 | |||
| 1ce55c272b | |||
| 972c781548 | |||
| a8a9b88d89 | |||
| 54b7dbb1c6 | |||
| 6ea98758ac | |||
| 079da2b384 | |||
| a5529352ad | |||
| 21a51fed05 | |||
| 2296ecf5b0 | |||
| aa2d400e8d | |||
| 8750d354b0 | |||
| ba9491220c | |||
| 6efa1c6dcb | |||
| 28e1dac334 | |||
| e5e47a3e88 | |||
| 1e2a09a469 | |||
| 2ef42fefd5 | |||
| c8cd8f090c | |||
| 33055e045d | |||
| 60793c02a5 | |||
| 17dfe8fc8a | |||
| 8055de2e9c | |||
| b8609a3917 | |||
| 6142f938bd | |||
| f24cd46b6b | |||
| ed5f69f576 | |||
| ce1d6f0cc8 | |||
| 2bd0f71785 | |||
| e6c03a18d2 | |||
| 78ea1c7ff9 | |||
| ff970b2519 | |||
| fe9af25bfb | |||
| 6e4e76262b | |||
| 86bfadb725 | |||
| 894882caf7 | |||
| 060dbd9ac9 | |||
| 5becae35af | |||
| 544ff232a9 | |||
| 980dbfd45c | |||
| 4f6d38e1ce | |||
| 9d4282c899 | |||
| 0eece9d283 | |||
| 95faf82065 | |||
| 02aabeb07e | |||
| f378470c0b | |||
| 7fcc248ddf | |||
| c32571dc47 | |||
| e00e0ec939 | |||
| 3ae367bb10 | |||
| 78db63442f | |||
| 2fe59376a1 | |||
| c27534ee93 | |||
| 8bd62b9ab0 | |||
| df8255447c | |||
| 59f13afcd2 | |||
| 0bc73851e1 | |||
| d643e9e0be | |||
| a583e8b9e8 | |||
| e20835878c | |||
| 07085d3260 | |||
| bec80c135e | |||
| 31d18243e9 | |||
| d7bfb7a5d1 | |||
| b6c6194da3 | |||
| a9a4b371d2 | |||
| 030fba6462 | |||
| a92c9c4694 |
+219
-49
@@ -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
|
||||
@@ -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
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"version": 1,
|
||||
"isRoot": true,
|
||||
"tools": {}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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 > 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 > real
|
||||
/// orange: real > bdgt*warning
|
||||
/// red: real > 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 > real
|
||||
/// orange: real > bdgt*warning
|
||||
/// red: real > 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">∑ (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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
+17
-25
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -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 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");
|
||||
}
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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
|
||||
@@ -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>
|
||||
@@ -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
Reference in New Issue
Block a user