Merge branch 'main' of https://git.marcoaiot.com/admin/marco.pms.web into pramod_Task#505
This commit is contained in:
commit
52a578972e
195
package-lock.json
generated
195
package-lock.json
generated
@ -9,6 +9,7 @@
|
|||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@hookform/resolvers": "^3.10.0",
|
"@hookform/resolvers": "^3.10.0",
|
||||||
|
"@microsoft/signalr": "^8.0.7",
|
||||||
"@reduxjs/toolkit": "^2.5.0",
|
"@reduxjs/toolkit": "^2.5.0",
|
||||||
"@types/web": "^0.0.216",
|
"@types/web": "^0.0.216",
|
||||||
"@vitejs/plugin-react": "^4.3.4",
|
"@vitejs/plugin-react": "^4.3.4",
|
||||||
@ -17,6 +18,7 @@
|
|||||||
"axios-retry": "^4.5.0",
|
"axios-retry": "^4.5.0",
|
||||||
"dotenv": "^16.4.7",
|
"dotenv": "^16.4.7",
|
||||||
"dotenv-webpack": "^8.1.0",
|
"dotenv-webpack": "^8.1.0",
|
||||||
|
"eventemitter3": "^5.0.1",
|
||||||
"jwt-decode": "^4.0.0",
|
"jwt-decode": "^4.0.0",
|
||||||
"localforage": "^1.10.0",
|
"localforage": "^1.10.0",
|
||||||
"match-sorter": "^6.3.1",
|
"match-sorter": "^6.3.1",
|
||||||
@ -827,6 +829,19 @@
|
|||||||
"@jridgewell/sourcemap-codec": "^1.4.14"
|
"@jridgewell/sourcemap-codec": "^1.4.14"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@microsoft/signalr": {
|
||||||
|
"version": "8.0.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/@microsoft/signalr/-/signalr-8.0.7.tgz",
|
||||||
|
"integrity": "sha512-PHcdMv8v5hJlBkRHAuKG5trGViQEkPYee36LnJQx4xHOQ5LL4X0nEWIxOp5cCtZ7tu+30quz5V3k0b1YNuc6lw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"abort-controller": "^3.0.0",
|
||||||
|
"eventsource": "^2.0.2",
|
||||||
|
"fetch-cookie": "^2.0.3",
|
||||||
|
"node-fetch": "^2.6.7",
|
||||||
|
"ws": "^7.4.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@nodelib/fs.scandir": {
|
"node_modules/@nodelib/fs.scandir": {
|
||||||
"version": "2.1.5",
|
"version": "2.1.5",
|
||||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
||||||
@ -1750,6 +1765,18 @@
|
|||||||
"integrity": "sha512-FQXkOta0XBSUPHndIKON2Y9JeQz5ZeMqLYZVVK93FliNBFm7LNMIZmY6FrMEB9XPcDbE2bekMbZD6kzDkxwYjA==",
|
"integrity": "sha512-FQXkOta0XBSUPHndIKON2Y9JeQz5ZeMqLYZVVK93FliNBFm7LNMIZmY6FrMEB9XPcDbE2bekMbZD6kzDkxwYjA==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/abort-controller": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"event-target-shim": "^5.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/acorn": {
|
"node_modules/acorn": {
|
||||||
"version": "8.14.0",
|
"version": "8.14.0",
|
||||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
|
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
|
||||||
@ -2980,10 +3007,19 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/event-target-shim": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/eventemitter3": {
|
"node_modules/eventemitter3": {
|
||||||
"version": "2.0.3",
|
"version": "5.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-2.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz",
|
||||||
"integrity": "sha512-jLN68Dx5kyFHaePoXWPsCGW5qdyZQtLYHkxkg02/Mz6g0kYpDx4FyP6XfArhQdlOC4b8Mv+EMxPo/8La7Tzghg==",
|
"integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/events": {
|
"node_modules/events": {
|
||||||
@ -2996,6 +3032,15 @@
|
|||||||
"node": ">=0.8.x"
|
"node": ">=0.8.x"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/eventsource": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/eventsource/-/eventsource-2.0.2.tgz",
|
||||||
|
"integrity": "sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/extend": {
|
"node_modules/extend": {
|
||||||
"version": "3.0.2",
|
"version": "3.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
||||||
@ -3051,6 +3096,16 @@
|
|||||||
"reusify": "^1.0.4"
|
"reusify": "^1.0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/fetch-cookie": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fetch-cookie/-/fetch-cookie-2.2.0.tgz",
|
||||||
|
"integrity": "sha512-h9AgfjURuCgA2+2ISl8GbavpUdR+WGAM2McW/ovn4tVccegp8ZqCKWSBR8uRdM8dDNlx5WdKRWxBYUwteLDCNQ==",
|
||||||
|
"license": "Unlicense",
|
||||||
|
"dependencies": {
|
||||||
|
"set-cookie-parser": "^2.4.8",
|
||||||
|
"tough-cookie": "^4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/file-entry-cache": {
|
"node_modules/file-entry-cache": {
|
||||||
"version": "6.0.1",
|
"version": "6.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
|
||||||
@ -4202,6 +4257,26 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true
|
"peer": true
|
||||||
},
|
},
|
||||||
|
"node_modules/node-fetch": {
|
||||||
|
"version": "2.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
|
||||||
|
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"whatwg-url": "^5.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "4.x || >=6.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"encoding": "^0.1.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"encoding": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/node-releases": {
|
"node_modules/node-releases": {
|
||||||
"version": "2.0.19",
|
"version": "2.0.19",
|
||||||
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
|
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
|
||||||
@ -4521,15 +4596,32 @@
|
|||||||
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
||||||
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
|
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
|
||||||
},
|
},
|
||||||
|
"node_modules/psl": {
|
||||||
|
"version": "1.15.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz",
|
||||||
|
"integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"punycode": "^2.3.1"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/lupomontero"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/punycode": {
|
"node_modules/punycode": {
|
||||||
"version": "2.3.1",
|
"version": "2.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
|
||||||
"integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
|
"integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/querystringify": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
|
||||||
|
"integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/queue-microtask": {
|
"node_modules/queue-microtask": {
|
||||||
"version": "1.2.3",
|
"version": "1.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
||||||
@ -4578,6 +4670,12 @@
|
|||||||
"node": ">=0.10"
|
"node": ">=0.10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/quill/node_modules/eventemitter3": {
|
||||||
|
"version": "2.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-2.0.3.tgz",
|
||||||
|
"integrity": "sha512-jLN68Dx5kyFHaePoXWPsCGW5qdyZQtLYHkxkg02/Mz6g0kYpDx4FyP6XfArhQdlOC4b8Mv+EMxPo/8La7Tzghg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/randombytes": {
|
"node_modules/randombytes": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
|
||||||
@ -4804,6 +4902,12 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/requires-port": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/reselect": {
|
"node_modules/reselect": {
|
||||||
"version": "5.1.1",
|
"version": "5.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz",
|
||||||
@ -5066,6 +5170,12 @@
|
|||||||
"randombytes": "^2.1.0"
|
"randombytes": "^2.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/set-cookie-parser": {
|
||||||
|
"version": "2.7.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz",
|
||||||
|
"integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/set-function-length": {
|
"node_modules/set-function-length": {
|
||||||
"version": "1.2.2",
|
"version": "1.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
|
||||||
@ -5441,6 +5551,27 @@
|
|||||||
"integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
|
"integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/tough-cookie": {
|
||||||
|
"version": "4.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz",
|
||||||
|
"integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==",
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
|
"dependencies": {
|
||||||
|
"psl": "^1.1.33",
|
||||||
|
"punycode": "^2.1.1",
|
||||||
|
"universalify": "^0.2.0",
|
||||||
|
"url-parse": "^1.5.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/tr46": {
|
||||||
|
"version": "0.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||||
|
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/tslib": {
|
"node_modules/tslib": {
|
||||||
"version": "1.14.1",
|
"version": "1.14.1",
|
||||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||||
@ -5567,6 +5698,15 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true
|
"peer": true
|
||||||
},
|
},
|
||||||
|
"node_modules/universalify": {
|
||||||
|
"version": "0.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
|
||||||
|
"integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/update-browserslist-db": {
|
"node_modules/update-browserslist-db": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz",
|
||||||
@ -5605,6 +5745,16 @@
|
|||||||
"punycode": "^2.1.0"
|
"punycode": "^2.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/url-parse": {
|
||||||
|
"version": "1.5.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
|
||||||
|
"integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"querystringify": "^2.1.1",
|
||||||
|
"requires-port": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/use-sync-external-store": {
|
"node_modules/use-sync-external-store": {
|
||||||
"version": "1.4.0",
|
"version": "1.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.4.0.tgz",
|
||||||
@ -5685,6 +5835,12 @@
|
|||||||
"node": ">=10.13.0"
|
"node": ">=10.13.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/webidl-conversions": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||||
|
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
|
||||||
|
"license": "BSD-2-Clause"
|
||||||
|
},
|
||||||
"node_modules/webpack": {
|
"node_modules/webpack": {
|
||||||
"version": "5.98.0",
|
"version": "5.98.0",
|
||||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.98.0.tgz",
|
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.98.0.tgz",
|
||||||
@ -5766,6 +5922,16 @@
|
|||||||
"node": ">=4.0"
|
"node": ">=4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/whatwg-url": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"tr46": "~0.0.3",
|
||||||
|
"webidl-conversions": "^3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/which": {
|
"node_modules/which": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||||
@ -5903,6 +6069,27 @@
|
|||||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
|
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/ws": {
|
||||||
|
"version": "7.5.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz",
|
||||||
|
"integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8.3.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"bufferutil": "^4.0.1",
|
||||||
|
"utf-8-validate": "^5.0.2"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"bufferutil": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"utf-8-validate": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/xlsx": {
|
"node_modules/xlsx": {
|
||||||
"version": "0.18.5",
|
"version": "0.18.5",
|
||||||
"resolved": "https://registry.npmjs.org/xlsx/-/xlsx-0.18.5.tgz",
|
"resolved": "https://registry.npmjs.org/xlsx/-/xlsx-0.18.5.tgz",
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@hookform/resolvers": "^3.10.0",
|
"@hookform/resolvers": "^3.10.0",
|
||||||
|
"@microsoft/signalr": "^8.0.7",
|
||||||
"@reduxjs/toolkit": "^2.5.0",
|
"@reduxjs/toolkit": "^2.5.0",
|
||||||
"@types/web": "^0.0.216",
|
"@types/web": "^0.0.216",
|
||||||
"@vitejs/plugin-react": "^4.3.4",
|
"@vitejs/plugin-react": "^4.3.4",
|
||||||
@ -20,6 +21,7 @@
|
|||||||
"axios-retry": "^4.5.0",
|
"axios-retry": "^4.5.0",
|
||||||
"dotenv": "^16.4.7",
|
"dotenv": "^16.4.7",
|
||||||
"dotenv-webpack": "^8.1.0",
|
"dotenv-webpack": "^8.1.0",
|
||||||
|
"eventemitter3": "^5.0.1",
|
||||||
"jwt-decode": "^4.0.0",
|
"jwt-decode": "^4.0.0",
|
||||||
"localforage": "^1.10.0",
|
"localforage": "^1.10.0",
|
||||||
"match-sorter": "^6.3.1",
|
"match-sorter": "^6.3.1",
|
||||||
|
@ -6,7 +6,9 @@ import RenderAttendanceStatus from "./RenderAttendanceStatus";
|
|||||||
import { useSelector, useDispatch } from "react-redux";
|
import { useSelector, useDispatch } from "react-redux";
|
||||||
import { fetchAttendanceData } from "../../slices/apiSlice/attedanceLogsSlice";
|
import { fetchAttendanceData } from "../../slices/apiSlice/attedanceLogsSlice";
|
||||||
import DateRangePicker from "../common/DateRangePicker";
|
import DateRangePicker from "../common/DateRangePicker";
|
||||||
import { getCachedData } from "../../slices/apiDataManager";
|
import { clearCacheKey, getCachedData } from "../../slices/apiDataManager";
|
||||||
|
import eventBus from "../../services/eventBus";
|
||||||
|
import AttendanceRepository from "../../repositories/AttendanceRepository";
|
||||||
|
|
||||||
const usePagination = (data, itemsPerPage) => {
|
const usePagination = (data, itemsPerPage) => {
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
@ -79,7 +81,7 @@ const AttendanceLog = ({
|
|||||||
setIsRefreshing(false);
|
setIsRefreshing(false);
|
||||||
}, [dateRange, projectId, dispatch, isRefreshing]);
|
}, [dateRange, projectId, dispatch, isRefreshing]);
|
||||||
|
|
||||||
useEffect(() => {
|
const filtering = (data) => {
|
||||||
const filteredData = showOnlyCheckout
|
const filteredData = showOnlyCheckout
|
||||||
? data.filter((item) => item.checkOutTime === null)
|
? data.filter((item) => item.checkOutTime === null)
|
||||||
: data;
|
: data;
|
||||||
@ -130,6 +132,10 @@ const AttendanceLog = ({
|
|||||||
// Create the final sorted array
|
// Create the final sorted array
|
||||||
const finalData = sortedDates.flatMap((date) => groupedByDate[date]);
|
const finalData = sortedDates.flatMap((date) => groupedByDate[date]);
|
||||||
setProcessedData(finalData);
|
setProcessedData(finalData);
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
filtering(data)
|
||||||
}, [data, showOnlyCheckout]);
|
}, [data, showOnlyCheckout]);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@ -145,6 +151,54 @@ const AttendanceLog = ({
|
|||||||
resetPage();
|
resetPage();
|
||||||
}, [processedData, resetPage]);
|
}, [processedData, resetPage]);
|
||||||
|
|
||||||
|
const handler = useCallback(
|
||||||
|
(msg) => {
|
||||||
|
const { startDate, endDate } = dateRange;
|
||||||
|
const checkIn = msg.response.checkInTime.substring(0, 10);
|
||||||
|
if (
|
||||||
|
projectId === msg.projectId &&
|
||||||
|
startDate <= checkIn &&
|
||||||
|
checkIn <= endDate
|
||||||
|
) {
|
||||||
|
const updatedAttendance = data.map((item) =>
|
||||||
|
item.id === msg.response.id
|
||||||
|
? { ...item, ...msg.response }
|
||||||
|
: item
|
||||||
|
);
|
||||||
|
|
||||||
|
filtering(updatedAttendance);
|
||||||
|
resetPage();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[projectId, dateRange, data, filtering, resetPage]
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
eventBus.on("attendance_log", handler);
|
||||||
|
return () => eventBus.off("attendance_log", handler);
|
||||||
|
}, [handler]);
|
||||||
|
|
||||||
|
const employeeHandler = useCallback(
|
||||||
|
(msg) => {
|
||||||
|
const { startDate, endDate } = dateRange;
|
||||||
|
if (data.some((item) => item.employeeId == msg.employeeId)) {
|
||||||
|
dispatch(
|
||||||
|
fetchAttendanceData({
|
||||||
|
projectId,
|
||||||
|
fromDate: startDate,
|
||||||
|
toDate: endDate,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[projectId, dateRange,data]
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
eventBus.on("employee", employeeHandler);
|
||||||
|
return () => eventBus.off("employee", employeeHandler);
|
||||||
|
}, [employeeHandler]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div
|
<div
|
||||||
|
@ -19,7 +19,7 @@ import InfraTable from "../Project/Infrastructure/InfraTable";
|
|||||||
|
|
||||||
const InfraPlanning = () =>
|
const InfraPlanning = () =>
|
||||||
{
|
{
|
||||||
const {profile: LoggedUser} = useProfile()
|
const {profile: LoggedUser, refetch : fetchData} = useProfile()
|
||||||
const dispatch = useDispatch()
|
const dispatch = useDispatch()
|
||||||
const {projects,loading:project_listLoader,error:projects_error} = useProjects()
|
const {projects,loading:project_listLoader,error:projects_error} = useProjects()
|
||||||
|
|
||||||
@ -72,7 +72,7 @@ const InfraPlanning = () =>
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
{(!project_deatilsLoader && projects_Details?.buildings?.length > 0) && (<InfraTable buildings={projects_Details?.buildings}/>)}
|
{(!project_deatilsLoader && projects_Details?.buildings?.length > 0) && (<InfraTable buildings={projects_Details?.buildings} projectId={projects_Details.id}/>)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
import React, { useCallback, useEffect, useState } from "react";
|
||||||
import Avatar from "../common/Avatar";
|
import Avatar from "../common/Avatar";
|
||||||
import { convertShortTime } from "../../utils/dateUtils";
|
import { convertShortTime } from "../../utils/dateUtils";
|
||||||
import RegularizationActions from "./RegularizationActions";
|
import RegularizationActions from "./RegularizationActions";
|
||||||
@ -6,6 +6,8 @@ import { useSelector } from "react-redux";
|
|||||||
import { useRegularizationRequests } from "../../hooks/useAttendance";
|
import { useRegularizationRequests } from "../../hooks/useAttendance";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import usePagination from "../../hooks/usePagination";
|
import usePagination from "../../hooks/usePagination";
|
||||||
|
import eventBus from "../../services/eventBus";
|
||||||
|
import { cacheData, clearCacheKey } from "../../slices/apiDataManager";
|
||||||
|
|
||||||
const Regularization = ({ handleRequest }) => {
|
const Regularization = ({ handleRequest }) => {
|
||||||
var selectedProject = useSelector((store) => store.localVariables.projectId);
|
var selectedProject = useSelector((store) => store.localVariables.projectId);
|
||||||
@ -22,16 +24,52 @@ const Regularization = ({ handleRequest }) => {
|
|||||||
const nameB = b.firstName.toLowerCase() + b.lastName.toLowerCase();
|
const nameB = b.firstName.toLowerCase() + b.lastName.toLowerCase();
|
||||||
return nameA?.localeCompare(nameB);
|
return nameA?.localeCompare(nameB);
|
||||||
};
|
};
|
||||||
const filteredData = [...regularizesList]?.sort(sortByName);
|
|
||||||
|
|
||||||
|
const handler = useCallback(
|
||||||
|
(msg) => {
|
||||||
|
if (selectedProject == msg.projectId) {
|
||||||
|
const updatedAttendance = regularizes?.filter( item => item.id !== msg.response.id );
|
||||||
|
cacheData("regularizedList", {
|
||||||
|
data: updatedAttendance,
|
||||||
|
projectId: selectedProject,
|
||||||
|
});
|
||||||
|
// clearCacheKey("regularizedList")
|
||||||
|
refetch();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[selectedProject, regularizes]
|
||||||
|
);
|
||||||
|
|
||||||
|
const filteredData = [...regularizesList]?.sort(sortByName);
|
||||||
|
|
||||||
const { currentPage, totalPages, currentItems, paginate } = usePagination(
|
const { currentPage, totalPages, currentItems, paginate } = usePagination(
|
||||||
filteredData,
|
filteredData,
|
||||||
10
|
10
|
||||||
);
|
);
|
||||||
|
useEffect(() => {
|
||||||
|
eventBus.on("regularization", handler);
|
||||||
|
return () => eventBus.off("regularization", handler);
|
||||||
|
}, [handler]);
|
||||||
|
|
||||||
|
const employeeHandler = useCallback(
|
||||||
|
(msg) => {
|
||||||
|
if (regularizes.some((item) => item.employeeId == msg.employeeId)) {
|
||||||
|
refetch();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[regularizes]
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
eventBus.on("employee", employeeHandler);
|
||||||
|
return () => eventBus.off("employee", employeeHandler);
|
||||||
|
}, [employeeHandler]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="table-responsive text-nowrap" style={{minHeight:"300px"}}>
|
<div
|
||||||
|
className="table-responsive text-nowrap"
|
||||||
|
style={{ minHeight: "300px" }}
|
||||||
|
>
|
||||||
<table className="table mb-0">
|
<table className="table mb-0">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@ -47,7 +85,11 @@ const Regularization = ({ handleRequest }) => {
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{loading && <td colSpan={6} className="text-center py-5">Loading...</td>}
|
{loading && (
|
||||||
|
<td colSpan={6} className="text-center py-5">
|
||||||
|
Loading...
|
||||||
|
</td>
|
||||||
|
)}
|
||||||
|
|
||||||
{!loading &&
|
{!loading &&
|
||||||
(regularizes?.length > 0 ? (
|
(regularizes?.length > 0 ? (
|
||||||
@ -55,7 +97,7 @@ const Regularization = ({ handleRequest }) => {
|
|||||||
<tr key={index}>
|
<tr key={index}>
|
||||||
<td colSpan={2}>
|
<td colSpan={2}>
|
||||||
<div className="d-flex justify-content-start align-items-center">
|
<div className="d-flex justify-content-start align-items-center">
|
||||||
<Avatar
|
<Avatar
|
||||||
firstName={att.firstName}
|
firstName={att.firstName}
|
||||||
lastName={att.lastName}
|
lastName={att.lastName}
|
||||||
></Avatar>
|
></Avatar>
|
||||||
@ -88,17 +130,22 @@ const Regularization = ({ handleRequest }) => {
|
|||||||
))
|
))
|
||||||
) : (
|
) : (
|
||||||
<tr>
|
<tr>
|
||||||
<td colSpan={6}
|
<td
|
||||||
className="text-center" style={{
|
colSpan={6}
|
||||||
|
className="text-center"
|
||||||
|
style={{
|
||||||
height: "200px",
|
height: "200px",
|
||||||
verticalAlign: "middle",
|
verticalAlign: "middle",
|
||||||
borderBottom: "none",
|
borderBottom: "none",
|
||||||
}}>No Record Found</td>
|
}}
|
||||||
|
>
|
||||||
|
No Record Found
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
))}
|
))}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
{!loading >10 && (
|
{!loading > 10 && (
|
||||||
<nav aria-label="Page ">
|
<nav aria-label="Page ">
|
||||||
<ul className="pagination pagination-sm justify-content-end py-1">
|
<ul className="pagination pagination-sm justify-content-end py-1">
|
||||||
<li className={`page-item ${currentPage === 1 ? "disabled" : ""}`}>
|
<li className={`page-item ${currentPage === 1 ? "disabled" : ""}`}>
|
||||||
@ -112,8 +159,9 @@ const Regularization = ({ handleRequest }) => {
|
|||||||
{[...Array(totalPages)].map((_, index) => (
|
{[...Array(totalPages)].map((_, index) => (
|
||||||
<li
|
<li
|
||||||
key={index}
|
key={index}
|
||||||
className={`page-item ${currentPage === index + 1 ? "active" : ""
|
className={`page-item ${
|
||||||
}`}
|
currentPage === index + 1 ? "active" : ""
|
||||||
|
}`}
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
className="page-link "
|
className="page-link "
|
||||||
@ -124,8 +172,9 @@ const Regularization = ({ handleRequest }) => {
|
|||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
<li
|
<li
|
||||||
className={`page-item ${currentPage === totalPages ? "disabled" : ""
|
className={`page-item ${
|
||||||
}`}
|
currentPage === totalPages ? "disabled" : ""
|
||||||
|
}`}
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
className="page-link "
|
className="page-link "
|
||||||
|
@ -1,8 +1,33 @@
|
|||||||
import React from "react";
|
import React, { useCallback, useEffect, useState } from "react";
|
||||||
import { useDashboardProjectsCardData } from "../../hooks/useDashboard_Data";
|
import { useDashboardProjectsCardData } from "../../hooks/useDashboard_Data";
|
||||||
|
import eventBus from "../../services/eventBus";
|
||||||
|
import GlobalRepository from "../../repositories/GlobalRepository";
|
||||||
|
|
||||||
const Projects = () => {
|
const Projects = () => {
|
||||||
const { projectsCardData } = useDashboardProjectsCardData();
|
const { projectsCardData } = useDashboardProjectsCardData();
|
||||||
|
const [projectData, setProjectsData] = useState(projectsCardData);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setProjectsData(projectsCardData);
|
||||||
|
}, [projectsCardData]);
|
||||||
|
|
||||||
|
const handler = useCallback(
|
||||||
|
async (msg) => {
|
||||||
|
try {
|
||||||
|
const response =
|
||||||
|
await GlobalRepository.getDashboardProjectsCardData();
|
||||||
|
setProjectsData(response.data);
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[GlobalRepository]
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
eventBus.on("project", handler);
|
||||||
|
return () => eventBus.off("project", handler);
|
||||||
|
}, [handler]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="card p-3 h-100 text-center d-flex justify-content-between">
|
<div className="card p-3 h-100 text-center d-flex justify-content-between">
|
||||||
@ -15,13 +40,13 @@ const Projects = () => {
|
|||||||
<div className="d-flex justify-content-around align-items-start mt-n2">
|
<div className="d-flex justify-content-around align-items-start mt-n2">
|
||||||
<div>
|
<div>
|
||||||
<h4 className="mb-0 fw-bold">
|
<h4 className="mb-0 fw-bold">
|
||||||
{projectsCardData.totalProjects?.toLocaleString()}
|
{projectData.totalProjects?.toLocaleString()}
|
||||||
</h4>
|
</h4>
|
||||||
<small className="text-muted">Total</small>
|
<small className="text-muted">Total</small>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h4 className="mb-0 fw-bold">
|
<h4 className="mb-0 fw-bold">
|
||||||
{projectsCardData.ongoingProjects?.toLocaleString()}
|
{projectData.ongoingProjects?.toLocaleString()}
|
||||||
</h4>
|
</h4>
|
||||||
<small className="text-muted">Ongoing</small>
|
<small className="text-muted">Ongoing</small>
|
||||||
</div>
|
</div>
|
||||||
@ -30,4 +55,4 @@ const Projects = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Projects;
|
export default Projects;
|
||||||
|
@ -1,9 +1,29 @@
|
|||||||
import React from "react";
|
import React, { useCallback, useEffect, useState } from "react";
|
||||||
import { useDashboardTeamsCardData } from "../../hooks/useDashboard_Data";
|
import { useDashboardTeamsCardData } from "../../hooks/useDashboard_Data";
|
||||||
|
import eventBus from "../../services/eventBus";
|
||||||
|
|
||||||
const Teams = () => {
|
const Teams = () => {
|
||||||
const { teamsCardData } = useDashboardTeamsCardData();
|
const { teamsCardData } = useDashboardTeamsCardData();
|
||||||
|
const[totalEmployees,setTotalEmployee] = useState(0);
|
||||||
|
const[inToday,setInToday] = useState(0);
|
||||||
|
|
||||||
|
useEffect(() =>{
|
||||||
|
setTotalEmployee(teamsCardData.totalEmployees)
|
||||||
|
setInToday(teamsCardData.inToday)
|
||||||
|
},[teamsCardData.totalEmployees,teamsCardData.inToday])
|
||||||
|
|
||||||
|
const handler = useCallback(
|
||||||
|
(msg) => {
|
||||||
|
if (msg.activity == 1) {
|
||||||
|
setInToday(prev => prev + 1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[inToday]
|
||||||
|
);
|
||||||
|
useEffect(() => {
|
||||||
|
eventBus.on("attendance", handler);
|
||||||
|
return () => eventBus.off("attendance", handler);
|
||||||
|
}, [handler]);
|
||||||
return (
|
return (
|
||||||
<div className="card p-3 h-100 text-center d-flex justify-content-between">
|
<div className="card p-3 h-100 text-center d-flex justify-content-between">
|
||||||
<div className="d-flex justify-content-start align-items-center mb-3">
|
<div className="d-flex justify-content-start align-items-center mb-3">
|
||||||
@ -14,13 +34,13 @@ const Teams = () => {
|
|||||||
<div className="d-flex justify-content-around align-items-start mt-n2">
|
<div className="d-flex justify-content-around align-items-start mt-n2">
|
||||||
<div>
|
<div>
|
||||||
<h4 className="mb-0 fw-bold">
|
<h4 className="mb-0 fw-bold">
|
||||||
{teamsCardData.totalEmployees?.toLocaleString()}
|
{totalEmployees?.toLocaleString()}
|
||||||
</h4>
|
</h4>
|
||||||
<small className="text-muted">Total Employees</small>
|
<small className="text-muted">Total Employees</small>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h4 className="mb-0 fw-bold">
|
<h4 className="mb-0 fw-bold">
|
||||||
{teamsCardData.inToday?.toLocaleString()}
|
{inToday?.toLocaleString()}
|
||||||
</h4>
|
</h4>
|
||||||
<small className="text-muted">In Today</small>
|
<small className="text-muted">In Today</small>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
import getGreetingMessage from "../../utils/greetingHandler";
|
import getGreetingMessage from "../../utils/greetingHandler";
|
||||||
import { clearAllCache } from "../../slices/apiDataManager";
|
import {
|
||||||
|
cacheData,
|
||||||
|
clearAllCache,
|
||||||
|
getCachedData,
|
||||||
|
} from "../../slices/apiDataManager";
|
||||||
import AuthRepository from "../../repositories/AuthRepository";
|
import AuthRepository from "../../repositories/AuthRepository";
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
import { changeMaster, setProjectId } from "../../slices/localVariablesSlice";
|
import { changeMaster, setProjectId } from "../../slices/localVariablesSlice";
|
||||||
@ -9,8 +13,11 @@ import { useLocation, useNavigate, useParams } from "react-router-dom";
|
|||||||
import Avatar from "../../components/common/Avatar";
|
import Avatar from "../../components/common/Avatar";
|
||||||
import { useChangePassword } from "../Context/ChangePasswordContext";
|
import { useChangePassword } from "../Context/ChangePasswordContext";
|
||||||
import { useProjects } from "../../hooks/useProjects";
|
import { useProjects } from "../../hooks/useProjects";
|
||||||
import { useEffect, useState } from "react";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
import { useProjectName } from "../../hooks/useProjects";
|
import { useProjectName } from "../../hooks/useProjects";
|
||||||
|
import eventBus from "../../services/eventBus";
|
||||||
|
import { useHasUserPermission } from "../../hooks/useHasUserPermission";
|
||||||
|
import { MANAGE_PROJECT } from "../../utils/constants";
|
||||||
|
|
||||||
const Header = () => {
|
const Header = () => {
|
||||||
const { profile } = useProfile();
|
const { profile } = useProfile();
|
||||||
@ -18,6 +25,7 @@ const Header = () => {
|
|||||||
const dispatch = useDispatch(changeMaster("Job Role"));
|
const dispatch = useDispatch(changeMaster("Job Role"));
|
||||||
const { data, loading } = useMaster();
|
const { data, loading } = useMaster();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
const HasManageProjectPermission = useHasUserPermission(MANAGE_PROJECT);
|
||||||
|
|
||||||
const getRole = (roles, joRoleId) => {
|
const getRole = (roles, joRoleId) => {
|
||||||
if (!Array.isArray(roles)) return "User";
|
if (!Array.isArray(roles)) return "User";
|
||||||
@ -64,7 +72,7 @@ const Header = () => {
|
|||||||
navigate(`/employee/${profile?.employeeInfo?.id}?for=attendance`);
|
navigate(`/employee/${profile?.employeeInfo?.id}?for=attendance`);
|
||||||
};
|
};
|
||||||
// const { projects, loading: projectLoading } = useProjects();
|
// const { projects, loading: projectLoading } = useProjects();
|
||||||
const { projectNames, loading: projectLoading } = useProjectName();
|
const { projectNames, loading: projectLoading, fetchData } = useProjectName();
|
||||||
|
|
||||||
const selectedProject = useSelector(
|
const selectedProject = useSelector(
|
||||||
(store) => store.localVariables.projectId
|
(store) => store.localVariables.projectId
|
||||||
@ -85,7 +93,11 @@ const Header = () => {
|
|||||||
|
|
||||||
const { openChangePassword } = useChangePassword();
|
const { openChangePassword } = useChangePassword();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (projectNames && selectedProject !== " ") {
|
if (
|
||||||
|
projectNames &&
|
||||||
|
selectedProject !== " " &&
|
||||||
|
!getCachedData("hasReceived")
|
||||||
|
) {
|
||||||
dispatch(setProjectId(projectNames[0]?.id));
|
dispatch(setProjectId(projectNames[0]?.id));
|
||||||
}
|
}
|
||||||
}, [projectNames]);
|
}, [projectNames]);
|
||||||
@ -93,6 +105,44 @@ const Header = () => {
|
|||||||
/** Check if current page id project details page */
|
/** Check if current page id project details page */
|
||||||
const isProjectPath = /^\/projects\/[a-f0-9-]{36}$/.test(location.pathname);
|
const isProjectPath = /^\/projects\/[a-f0-9-]{36}$/.test(location.pathname);
|
||||||
|
|
||||||
|
const handler = useCallback(
|
||||||
|
async (data) => {
|
||||||
|
if (!HasManageProjectPermission) {
|
||||||
|
await fetchData();
|
||||||
|
const projectExist = data.projectIds.some(
|
||||||
|
(item) => item == selectedProject
|
||||||
|
);
|
||||||
|
if (projectExist) {
|
||||||
|
cacheData("hasReceived", false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[fetchData,projectNames,selectedProject]
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
eventBus.on("assign_project_one", handler);
|
||||||
|
return () => eventBus.off("assign_project_one", handler);
|
||||||
|
}, [handler]);
|
||||||
|
|
||||||
|
const newProjectHandler = useCallback(
|
||||||
|
async (msg) => {
|
||||||
|
|
||||||
|
if (HasManageProjectPermission && msg.keyword === "Create_Project") {
|
||||||
|
await fetchData();
|
||||||
|
} else if (projectNames.some((item) => item.id == msg.response.id)) {
|
||||||
|
console.log((projectNames.some((item) => item.id == msg.response.id)))
|
||||||
|
await fetchData();
|
||||||
|
}
|
||||||
|
cacheData("hasReceived", false);
|
||||||
|
},
|
||||||
|
[HasManageProjectPermission,projectNames]
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
eventBus.on("project", newProjectHandler);
|
||||||
|
return () => eventBus.off("project", newProjectHandler);
|
||||||
|
}, [handler]);
|
||||||
return (
|
return (
|
||||||
<nav
|
<nav
|
||||||
className="layout-navbar container-xxl navbar navbar-expand-xl navbar-detached align-items-center bg-navbar-theme"
|
className="layout-navbar container-xxl navbar navbar-expand-xl navbar-detached align-items-center bg-navbar-theme"
|
||||||
@ -169,7 +219,6 @@ const Header = () => {
|
|||||||
<li className="nav-item dropdown-shortcuts navbar-dropdown dropdown me-2 me-xl-0">
|
<li className="nav-item dropdown-shortcuts navbar-dropdown dropdown me-2 me-xl-0">
|
||||||
<a
|
<a
|
||||||
className="nav-link dropdown-toggle hide-arrow"
|
className="nav-link dropdown-toggle hide-arrow"
|
||||||
|
|
||||||
data-bs-toggle="dropdown"
|
data-bs-toggle="dropdown"
|
||||||
data-bs-auto-close="true"
|
data-bs-auto-close="true"
|
||||||
aria-expanded="false"
|
aria-expanded="false"
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import { getProjectStatusName } from "../../utils/projectStatus";
|
import { getProjectStatusName } from "../../utils/projectStatus";
|
||||||
const AboutProject = ({ data }) => {
|
const AboutProject = ({ data }) => {
|
||||||
const [CurrentProject, setCurrentProject] = useState(data);
|
const [CurrentProject, setCurrentProject] = useState(data);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setCurrentProject(data);
|
||||||
|
}, [data]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{data && (
|
{data && (
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { useState, useEffect, useRef } from "react";
|
import React, { useState, useEffect, useRef, useCallback } from "react";
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
import { changeMaster } from "../../slices/localVariablesSlice";
|
import { changeMaster } from "../../slices/localVariablesSlice";
|
||||||
import useMaster from "../../hooks/masterHook/useMaster";
|
import useMaster from "../../hooks/masterHook/useMaster";
|
||||||
@ -10,6 +10,7 @@ import { useEmployeesAllOrByProjectId } from "../../hooks/useEmployees";
|
|||||||
import { TasksRepository } from "../../repositories/ProjectRepository";
|
import { TasksRepository } from "../../repositories/ProjectRepository";
|
||||||
import showToast from "../../services/toastService";
|
import showToast from "../../services/toastService";
|
||||||
import { useProjectDetails } from "../../hooks/useProjects";
|
import { useProjectDetails } from "../../hooks/useProjects";
|
||||||
|
import eventBus from "../../services/eventBus";
|
||||||
|
|
||||||
const AssignTask = ({ assignData, onClose, setAssigned }) => {
|
const AssignTask = ({ assignData, onClose, setAssigned }) => {
|
||||||
const maxPlanned =
|
const maxPlanned =
|
||||||
@ -75,10 +76,11 @@ const AssignTask = ({ assignData, onClose, setAssigned }) => {
|
|||||||
const selectedProject = useSelector(
|
const selectedProject = useSelector(
|
||||||
(store) => store.localVariables.projectId
|
(store) => store.localVariables.projectId
|
||||||
);
|
);
|
||||||
const { employees, loading: employeeLoading } = useEmployeesAllOrByProjectId(
|
const {
|
||||||
selectedProject,
|
employees,
|
||||||
false
|
loading: employeeLoading,
|
||||||
);
|
recallEmployeeData,
|
||||||
|
} = useEmployeesAllOrByProjectId(selectedProject, false);
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const { loading } = useMaster(); // Assuming this is for jobRoleData loading
|
const { loading } = useMaster(); // Assuming this is for jobRoleData loading
|
||||||
const jobRoleData = getCachedData("Job Role");
|
const jobRoleData = getCachedData("Job Role");
|
||||||
|
@ -96,7 +96,9 @@ const BuildingModel = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setBuildings(projects_Details.data?.buildings);
|
if(projects_Details){
|
||||||
|
setBuildings(projects_Details.data?.buildings);
|
||||||
|
}
|
||||||
}, [projects_Details]);
|
}, [projects_Details]);
|
||||||
return (
|
return (
|
||||||
<div className="modal-dialog modal-lg modal-simple modal-edit-user">
|
<div className="modal-dialog modal-lg modal-simple modal-edit-user">
|
||||||
|
@ -1,11 +1,17 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
import Building from "./Building";
|
import Building from "./Building";
|
||||||
import Floor from "./Floor";
|
import Floor from "./Floor";
|
||||||
import FloorModel from "./FloorModel";
|
import FloorModel from "./FloorModel";
|
||||||
import showToast from "../../../services/toastService";
|
import showToast from "../../../services/toastService";
|
||||||
import ProjectRepository from "../../../repositories/ProjectRepository";
|
import ProjectRepository from "../../../repositories/ProjectRepository";
|
||||||
|
import eventBus from "../../../services/eventBus";
|
||||||
|
import {
|
||||||
|
cacheData,
|
||||||
|
clearCacheKey,
|
||||||
|
getCachedData,
|
||||||
|
} from "../../../slices/apiDataManager";
|
||||||
|
|
||||||
const InfraTable = ({ buildings }) => {
|
const InfraTable = ({ buildings, projectId, signalRHandler }) => {
|
||||||
const [projectBuilding, setProjectBuilding] = useState([]);
|
const [projectBuilding, setProjectBuilding] = useState([]);
|
||||||
const [expandedBuildings, setExpandedBuildings] = useState([]);
|
const [expandedBuildings, setExpandedBuildings] = useState([]);
|
||||||
const [showFloorModal, setShowFloorModal] = useState(false);
|
const [showFloorModal, setShowFloorModal] = useState(false);
|
||||||
@ -108,12 +114,41 @@ const InfraTable = ({ buildings }) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (buildings && buildings.length > 0) {
|
if (buildings && buildings.length > 0) {
|
||||||
setProjectBuilding(buildings);
|
setProjectBuilding(buildings);
|
||||||
setExpandedBuildings([buildings[0].id]);
|
setExpandedBuildings([buildings[0].id]);
|
||||||
}
|
}
|
||||||
}, [buildings]);
|
}, [buildings]);
|
||||||
|
|
||||||
|
const handler = useCallback(
|
||||||
|
(msg) => {
|
||||||
|
if (msg.projectIds.some((item) => item == projectId)) {
|
||||||
|
try {
|
||||||
|
ProjectRepository.getProjectByprojectId(projectId)
|
||||||
|
.then((response) => {
|
||||||
|
cacheData("projectInfo", {
|
||||||
|
projectId: projectId,
|
||||||
|
data: response.data,
|
||||||
|
});
|
||||||
|
setProjectBuilding(response?.data?.buildings);
|
||||||
|
signalRHandler?.(response?.data);
|
||||||
|
showToast(msg.message, "info");
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error(error);
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[buildings]
|
||||||
|
);
|
||||||
|
useEffect(() => {
|
||||||
|
eventBus.on("infra", handler);
|
||||||
|
return () => eventBus.off("infra", handler);
|
||||||
|
}, [handler]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{projectBuilding && projectBuilding.length > 0 && (
|
{projectBuilding && projectBuilding.length > 0 && (
|
||||||
|
@ -263,7 +263,7 @@ const ManageProjectInfo = ({ project, handleSubmitForm, onClose }) => {
|
|||||||
<option value="b74da4c2-d07e-46f2-9919-e75e49b12731">Active</option>
|
<option value="b74da4c2-d07e-46f2-9919-e75e49b12731">Active</option>
|
||||||
<option value="603e994b-a27f-4e5d-a251-f3d69b0498ba">On Hold</option>
|
<option value="603e994b-a27f-4e5d-a251-f3d69b0498ba">On Hold</option>
|
||||||
|
|
||||||
{/* <option value="3">Suspended</option> */}
|
<option value="cdad86aa-8a56-4ff4-b633-9c629057dfef">In Progress</option>
|
||||||
<option value="ef1c356e-0fe0-42df-a5d3-8daee355492d">Inactive</option>
|
<option value="ef1c356e-0fe0-42df-a5d3-8daee355492d">Inactive</option>
|
||||||
|
|
||||||
<option value="33deaef9-9af1-4f2a-b443-681ea0d04f81">Completed</option>
|
<option value="33deaef9-9af1-4f2a-b443-681ea0d04f81">Completed</option>
|
||||||
|
@ -117,7 +117,7 @@ const MapUsers = ({
|
|||||||
<div className="modal-dialog modal-dialog-scrollable mx-sm-auto mx-1 modal-lg modal-simple modal-edit-user">
|
<div className="modal-dialog modal-dialog-scrollable mx-sm-auto mx-1 modal-lg modal-simple modal-edit-user">
|
||||||
<div className="modal-content">
|
<div className="modal-content">
|
||||||
<div className="modal-header text-center">
|
<div className="modal-header text-center">
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close">
|
<button type="button" className="btn-close" data-bs-dismiss="modal" aria-label="Close">
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<p className="m-0 fw-semibold fs-5">Assign Employee</p>
|
<p className="m-0 fw-semibold fs-5">Assign Employee</p>
|
||||||
|
@ -12,10 +12,15 @@ const ProjectBanner = ({ project_data }) => {
|
|||||||
const [showModal, setShowModal] = useState(false);
|
const [showModal, setShowModal] = useState(false);
|
||||||
const manageProject = useHasUserPermission(MANAGE_PROJECT);
|
const manageProject = useHasUserPermission(MANAGE_PROJECT);
|
||||||
const [CurrentProject, setCurrentProject] = useState(project_data);
|
const [CurrentProject, setCurrentProject] = useState(project_data);
|
||||||
|
|
||||||
if (project_data == null) {
|
if (project_data == null) {
|
||||||
return <span>incomplete project information</span>;
|
return <span>incomplete project information</span>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setCurrentProject(project_data);
|
||||||
|
}, [project_data]);
|
||||||
|
|
||||||
const handleShow = () => setShowModal(true);
|
const handleShow = () => setShowModal(true);
|
||||||
const handleClose = () => setShowModal(false);
|
const handleClose = () => setShowModal(false);
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import { getDateDifferenceInDays } from "../../utils/dateUtils";
|
import { getDateDifferenceInDays } from "../../utils/dateUtils";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
@ -22,6 +22,10 @@ const ProjectCard = ({ projectData, recall }) => {
|
|||||||
const ManageProject = useHasUserPermission(MANAGE_PROJECT);
|
const ManageProject = useHasUserPermission(MANAGE_PROJECT);
|
||||||
const [modifyProjectLoading, setMdifyProjectLoading] = useState(false);
|
const [modifyProjectLoading, setMdifyProjectLoading] = useState(false);
|
||||||
|
|
||||||
|
useEffect(()=>{
|
||||||
|
setProjectInfo(projectData);
|
||||||
|
},[projectData])
|
||||||
|
// console.log("in card view",projectInfo);
|
||||||
const handleShow = async () => {
|
const handleShow = async () => {
|
||||||
try {
|
try {
|
||||||
setMdifyProjectLoading(true);
|
setMdifyProjectLoading(true);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect, useCallback } from "react";
|
||||||
import "./ProjectInfra.css";
|
import "./ProjectInfra.css";
|
||||||
import BuildingModel from "./Infrastructure/BuildingModel";
|
import BuildingModel from "./Infrastructure/BuildingModel";
|
||||||
import FloorModel from "./Infrastructure/FloorModel";
|
import FloorModel from "./Infrastructure/FloorModel";
|
||||||
@ -12,20 +12,20 @@ import ProjectModal from "./ProjectModal";
|
|||||||
import { useHasUserPermission } from "../../hooks/useHasUserPermission";
|
import { useHasUserPermission } from "../../hooks/useHasUserPermission";
|
||||||
import { MANAGE_PROJECT_INFRA } from "../../utils/constants";
|
import { MANAGE_PROJECT_INFRA } from "../../utils/constants";
|
||||||
import InfraTable from "./Infrastructure/InfraTable";
|
import InfraTable from "./Infrastructure/InfraTable";
|
||||||
import { cacheData, clearCacheKey, getCachedData } from "../../slices/apiDataManager";
|
import {
|
||||||
|
cacheData,
|
||||||
|
clearCacheKey,
|
||||||
|
getCachedData,
|
||||||
|
} from "../../slices/apiDataManager";
|
||||||
import { useProjectDetails } from "../../hooks/useProjects";
|
import { useProjectDetails } from "../../hooks/useProjects";
|
||||||
import {useDispatch, useSelector} from "react-redux";
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
import {refreshData} from "../../slices/localVariablesSlice";
|
import { refreshData } from "../../slices/localVariablesSlice";
|
||||||
|
import eventBus from "../../services/eventBus";
|
||||||
|
|
||||||
const ProjectInfra = ({
|
const ProjectInfra = ({ data, onDataChange, eachSiteEngineer }) => {
|
||||||
data,
|
const reloadedData = useSelector((store) => store.localVariables.reload);
|
||||||
onDataChange,
|
|
||||||
eachSiteEngineer,
|
|
||||||
} ) =>
|
|
||||||
{
|
|
||||||
const reloadedData = useSelector((store)=>store.localVariables.reload)
|
|
||||||
const [expandedBuildings, setExpandedBuildings] = useState([]);
|
const [expandedBuildings, setExpandedBuildings] = useState([]);
|
||||||
const { projects_Details,refetch, loading } = useProjectDetails(data?.id);
|
const { projects_Details, refetch, loading } = useProjectDetails(data?.id);
|
||||||
const [project, setProject] = useState(projects_Details);
|
const [project, setProject] = useState(projects_Details);
|
||||||
const [modalConfig, setModalConfig] = useState({ type: null, data: null });
|
const [modalConfig, setModalConfig] = useState({ type: null, data: null });
|
||||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||||
@ -39,8 +39,8 @@ const ProjectInfra = ({
|
|||||||
const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);
|
const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);
|
||||||
const [clearFormTrigger, setClearFormTrigger] = useState(false);
|
const [clearFormTrigger, setClearFormTrigger] = useState(false);
|
||||||
const [CurrentBuilding, setCurrentBuilding] = useState("");
|
const [CurrentBuilding, setCurrentBuilding] = useState("");
|
||||||
const [ showModal, setShowModal ] = useState( false );
|
const [showModal, setShowModal] = useState(false);
|
||||||
const dispatch = useDispatch()
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setProject(projects_Details);
|
setProject(projects_Details);
|
||||||
@ -143,8 +143,8 @@ const ProjectInfra = ({
|
|||||||
existingItem.workItemId ===
|
existingItem.workItemId ===
|
||||||
workItem.workItemId
|
workItem.workItemId
|
||||||
)
|
)
|
||||||
? [...workArea.workItems] // Create a new array to trigger re-render
|
? [...workArea.workItems] // Create a new array to trigger re-render
|
||||||
: [...workArea.workItems, workItem],
|
: [...workArea.workItems, workItem],
|
||||||
}
|
}
|
||||||
: workArea
|
: workArea
|
||||||
),
|
),
|
||||||
@ -156,15 +156,15 @@ const ProjectInfra = ({
|
|||||||
);
|
);
|
||||||
updatedProject.buildings = updatedBuildings;
|
updatedProject.buildings = updatedBuildings;
|
||||||
// workItem update, but having local state issue there for needed to calling api
|
// workItem update, but having local state issue there for needed to calling api
|
||||||
clearCacheKey( "projectInfo" )
|
clearCacheKey("projectInfo");
|
||||||
refetch()
|
refetch();
|
||||||
|
|
||||||
cacheData("projectInfo", {
|
cacheData("projectInfo", {
|
||||||
projectId: updatedProject.id,
|
projectId: updatedProject.id,
|
||||||
data: updatedProject,
|
data: updatedProject,
|
||||||
});
|
});
|
||||||
|
|
||||||
setProject( updatedProject );
|
setProject(updatedProject);
|
||||||
// closeTaskModel()
|
// closeTaskModel()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -173,11 +173,8 @@ const ProjectInfra = ({
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const submitData = async (infraObject) => {
|
const submitData = async (infraObject) => {
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
|
|
||||||
let response = await ProjectRepository.manageProjectInfra(infraObject);
|
let response = await ProjectRepository.manageProjectInfra(infraObject);
|
||||||
const entity = response.data;
|
const entity = response.data;
|
||||||
|
|
||||||
@ -209,9 +206,8 @@ const ProjectInfra = ({
|
|||||||
setProject((prevProject) => ({
|
setProject((prevProject) => ({
|
||||||
...prevProject,
|
...prevProject,
|
||||||
buildings: updatedBuildings,
|
buildings: updatedBuildings,
|
||||||
} ) );
|
}));
|
||||||
// closeBuildingModel()
|
// closeBuildingModel()
|
||||||
|
|
||||||
}
|
}
|
||||||
// Handle the floor data
|
// Handle the floor data
|
||||||
else if (entity.floor) {
|
else if (entity.floor) {
|
||||||
@ -247,12 +243,11 @@ const ProjectInfra = ({
|
|||||||
projectId: updatedProject.id,
|
projectId: updatedProject.id,
|
||||||
data: updatedProject,
|
data: updatedProject,
|
||||||
});
|
});
|
||||||
setProject( updatedProject );
|
setProject(updatedProject);
|
||||||
// closeFloorModel()
|
// closeFloorModel()
|
||||||
}
|
}
|
||||||
// Handle the work area data
|
// Handle the work area data
|
||||||
else if ( entity.workArea )
|
else if (entity.workArea) {
|
||||||
{
|
|
||||||
let buildingId = infraObject[0].workArea.buildingId;
|
let buildingId = infraObject[0].workArea.buildingId;
|
||||||
|
|
||||||
const { floorId, areaName, id } = entity.workArea;
|
const { floorId, areaName, id } = entity.workArea;
|
||||||
@ -291,7 +286,7 @@ const ProjectInfra = ({
|
|||||||
projectId: updatedProject.id,
|
projectId: updatedProject.id,
|
||||||
data: updatedProject,
|
data: updatedProject,
|
||||||
});
|
});
|
||||||
setProject( updatedProject );
|
setProject(updatedProject);
|
||||||
// closeWorkAreaModel()
|
// closeWorkAreaModel()
|
||||||
}
|
}
|
||||||
// Handle the task (workItem) data
|
// Handle the task (workItem) data
|
||||||
@ -303,7 +298,6 @@ const ProjectInfra = ({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const toggleBuilding = (id) => {
|
const toggleBuilding = (id) => {
|
||||||
setExpandedBuildings((prev) =>
|
setExpandedBuildings((prev) =>
|
||||||
prev.includes(id) ? prev.filter((bid) => bid !== id) : [...prev, id]
|
prev.includes(id) ? prev.filter((bid) => bid !== id) : [...prev, id]
|
||||||
@ -344,15 +338,17 @@ const ProjectInfra = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleShow = () => setShowModal(true);
|
const handleShow = () => setShowModal(true);
|
||||||
const handleClose = () => setShowModal( false );
|
const handleClose = () => setShowModal(false);
|
||||||
useEffect( () =>
|
useEffect(() => {
|
||||||
{
|
if (reloadedData) {
|
||||||
if (reloadedData)
|
refetch();
|
||||||
{
|
dispatch(refreshData(false));
|
||||||
refetch()
|
}
|
||||||
dispatch( refreshData( false ) )
|
}, [reloadedData]);
|
||||||
}
|
|
||||||
},[reloadedData])
|
const signalRHandler = (response) => {
|
||||||
|
setProject(response);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -420,7 +416,6 @@ const ProjectInfra = ({
|
|||||||
>
|
>
|
||||||
<TaskModel
|
<TaskModel
|
||||||
project={project}
|
project={project}
|
||||||
|
|
||||||
onClose={closeTaskModel}
|
onClose={closeTaskModel}
|
||||||
onSubmit={handleTaskModelFormSubmit}
|
onSubmit={handleTaskModelFormSubmit}
|
||||||
clearTrigger={clearFormTrigger}
|
clearTrigger={clearFormTrigger}
|
||||||
@ -482,8 +477,9 @@ const ProjectInfra = ({
|
|||||||
{project && project.buildings?.length > 0 && (
|
{project && project.buildings?.length > 0 && (
|
||||||
<InfraTable
|
<InfraTable
|
||||||
buildings={project?.buildings}
|
buildings={project?.buildings}
|
||||||
project={project}
|
projectId={project.id}
|
||||||
handleFloor={submitData}
|
handleFloor={submitData}
|
||||||
|
signalRHandler = {signalRHandler}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect, useCallback } from "react";
|
||||||
import MapUsers from "./MapUsers";
|
import MapUsers from "./MapUsers";
|
||||||
import { Link, NavLink, useNavigate } from "react-router-dom";
|
import { Link, NavLink, useNavigate } from "react-router-dom";
|
||||||
|
|
||||||
@ -13,6 +13,7 @@ import useMaster from "../../hooks/masterHook/useMaster";
|
|||||||
import { useHasUserPermission } from "../../hooks/useHasUserPermission";
|
import { useHasUserPermission } from "../../hooks/useHasUserPermission";
|
||||||
import { ASSIGN_TO_PROJECT } from "../../utils/constants";
|
import { ASSIGN_TO_PROJECT } from "../../utils/constants";
|
||||||
import ConfirmModal from "../common/ConfirmModal";
|
import ConfirmModal from "../common/ConfirmModal";
|
||||||
|
import eventBus from "../../services/eventBus";
|
||||||
|
|
||||||
const Teams = ({ project }) => {
|
const Teams = ({ project }) => {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
@ -173,6 +174,33 @@ const Teams = ({ project }) => {
|
|||||||
}
|
}
|
||||||
const closeDeleteModal = ()=> setIsDeleteModal(false)
|
const closeDeleteModal = ()=> setIsDeleteModal(false)
|
||||||
|
|
||||||
|
const handler = useCallback(
|
||||||
|
(msg) => {
|
||||||
|
if (msg.projectIds.some((item) => item === project.id)) {
|
||||||
|
fetchEmployees();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
eventBus.on("assign_project_all", handler);
|
||||||
|
return () => eventBus.off("assign_project_all", handler);
|
||||||
|
}, [handler]);
|
||||||
|
|
||||||
|
const employeeHandler = useCallback(
|
||||||
|
(msg) => {
|
||||||
|
if(filteredEmployees.some((item) => item.employeeId == msg.employeeId)){
|
||||||
|
fetchEmployees();
|
||||||
|
}
|
||||||
|
},[filteredEmployees]
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
eventBus.on("employee",employeeHandler);
|
||||||
|
return () => eventBus.off("employee",employeeHandler)
|
||||||
|
},[employeeHandler])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div
|
<div
|
||||||
@ -322,10 +350,10 @@ const Teams = ({ project }) => {
|
|||||||
{" "}
|
{" "}
|
||||||
{removingEmployeeId === item.id ? (
|
{removingEmployeeId === item.id ? (
|
||||||
<div
|
<div
|
||||||
class="spinner-border spinner-border-sm text-primary"
|
className="spinner-border spinner-border-sm text-primary"
|
||||||
role="status"
|
role="status"
|
||||||
>
|
>
|
||||||
<span class="visually-hidden">
|
<span className="visually-hidden">
|
||||||
Loading...
|
Loading...
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -37,7 +37,7 @@ export const useAttendace =(projectId)=>{
|
|||||||
}
|
}
|
||||||
},[projectId])
|
},[projectId])
|
||||||
|
|
||||||
return {attendance,loading,error}
|
return {attendance,loading,error,recall:fetchData}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useEmployeeAttendacesLog = (id) => {
|
export const useEmployeeAttendacesLog = (id) => {
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
import {useState,useEffect} from "react";
|
import {useState,useEffect, useCallback} from "react";
|
||||||
import AuthRepository from "../repositories/AuthRepository";
|
import AuthRepository from "../repositories/AuthRepository";
|
||||||
import {cacheProfileData, getCachedProfileData} from "../slices/apiDataManager";
|
import {cacheData, cacheProfileData, getCachedData, getCachedProfileData} from "../slices/apiDataManager";
|
||||||
import {useSelector} from "react-redux";
|
import {useSelector} from "react-redux";
|
||||||
|
import eventBus from "../services/eventBus";
|
||||||
|
|
||||||
let hasFetched = false;
|
let hasFetched = false;
|
||||||
|
let hasReceived = false;
|
||||||
|
|
||||||
export const useProfile = () => {
|
export const useProfile = () => {
|
||||||
const loggedUser = useSelector( ( store ) => store.globalVariables.loginUser );
|
const loggedUser = useSelector( ( store ) => store.globalVariables.loginUser );
|
||||||
@ -24,7 +26,7 @@ export const useProfile = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
const validation = () => {
|
||||||
if (!hasFetched) {
|
if (!hasFetched) {
|
||||||
hasFetched = true;
|
hasFetched = true;
|
||||||
if (!loggedUser) {
|
if (!loggedUser) {
|
||||||
@ -35,8 +37,26 @@ export const useProfile = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setProfile(loggedUser);
|
setProfile(loggedUser);
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
validation();
|
||||||
}, [loggedUser]);
|
}, [loggedUser]);
|
||||||
|
|
||||||
|
const handler = useCallback(
|
||||||
|
(data) => {
|
||||||
|
if(!getCachedData("hasReceived")){
|
||||||
|
cacheData("hasReceived", true);
|
||||||
|
hasFetched = false;
|
||||||
|
validation();
|
||||||
|
}
|
||||||
|
},[]
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
eventBus.on("assign_project_one", handler);
|
||||||
|
return () => eventBus.off("assign_project_one", handler);
|
||||||
|
}, [handler]);
|
||||||
|
|
||||||
return { profile, loading, error };
|
return { profile, loading, error };
|
||||||
};
|
};
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
import { cacheData, getCachedData } from "../slices/apiDataManager";
|
import { cacheData, getCachedData } from "../slices/apiDataManager";
|
||||||
import ProjectRepository from "../repositories/ProjectRepository";
|
import ProjectRepository from "../repositories/ProjectRepository";
|
||||||
import { useProfile } from "./useProfile";
|
import { useProfile } from "./useProfile";
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
import { setProjectId } from "../slices/localVariablesSlice";
|
import { setProjectId } from "../slices/localVariablesSlice";
|
||||||
import EmployeeList from "../components/Directory/EmployeeList";
|
import EmployeeList from "../components/Directory/EmployeeList";
|
||||||
|
import eventBus from "../services/eventBus";
|
||||||
|
|
||||||
export const useProjects = () => {
|
export const useProjects = () => {
|
||||||
const loggedUser = useSelector((store) => store.globalVariables.loginUser);
|
const loggedUser = useSelector((store) => store.globalVariables.loginUser);
|
||||||
@ -174,6 +175,7 @@ export const useProjectName = () => {
|
|||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [projectNames, setProjectName] = useState([]);
|
const [projectNames, setProjectName] = useState([]);
|
||||||
const [Error, setError] = useState();
|
const [Error, setError] = useState();
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
const fetchData = async () => {
|
const fetchData = async () => {
|
||||||
try {
|
try {
|
||||||
@ -181,6 +183,9 @@ export const useProjectName = () => {
|
|||||||
setProjectName(response.data);
|
setProjectName(response.data);
|
||||||
cacheData("basicProjectNameList", response.data);
|
cacheData("basicProjectNameList", response.data);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
|
if(response.data.length === 1){
|
||||||
|
dispatch(setProjectId(response.data[0]?.id));
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
setError("Failed to fetch data.");
|
setError("Failed to fetch data.");
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
@ -190,5 +195,5 @@ export const useProjectName = () => {
|
|||||||
fetchData();
|
fetchData();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return { projectNames, loading, Error };
|
return { projectNames, loading, Error, fetchData };
|
||||||
};
|
};
|
||||||
|
@ -2,15 +2,26 @@ import React, { useEffect } from "react";
|
|||||||
import { Outlet } from "react-router-dom";
|
import { Outlet } from "react-router-dom";
|
||||||
import Header from "../components/Layout/Header";
|
import Header from "../components/Layout/Header";
|
||||||
import Sidebar from "../components/Layout/Sidebar";
|
import Sidebar from "../components/Layout/Sidebar";
|
||||||
|
import { startSignalR, stopSignalR } from "../services/signalRService";
|
||||||
import Footer from "../components/Layout/Footer";
|
import Footer from "../components/Layout/Footer";
|
||||||
import FloatingMenu from "../components/common/FloatingMenu";
|
import FloatingMenu from "../components/common/FloatingMenu";
|
||||||
import { FabProvider } from "../Context/FabContext";
|
import { FabProvider } from "../Context/FabContext";
|
||||||
|
import { useSelector } from "react-redux";
|
||||||
|
|
||||||
const HomeLayout = () => {
|
const HomeLayout = () => {
|
||||||
|
const loggedUser = useSelector((store) => store.globalVariables.loginUser);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
Main();
|
Main();
|
||||||
}, []);
|
}, []);
|
||||||
|
useEffect(() => {
|
||||||
|
if (loggedUser) {
|
||||||
|
startSignalR(loggedUser);
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
stopSignalR();
|
||||||
|
};
|
||||||
|
}, [loggedUser]);
|
||||||
return (
|
return (
|
||||||
<FabProvider>
|
<FabProvider>
|
||||||
<div className="layout-wrapper layout-content-navbar">
|
<div className="layout-wrapper layout-content-navbar">
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect, useCallback } from "react";
|
||||||
import {
|
import {
|
||||||
cacheData,
|
cacheData,
|
||||||
|
clearCacheKey,
|
||||||
getCachedData,
|
getCachedData,
|
||||||
getCachedProfileData,
|
getCachedProfileData,
|
||||||
} from "../../slices/apiDataManager";
|
} from "../../slices/apiDataManager";
|
||||||
@ -18,6 +19,8 @@ import { markCurrentAttendance } from "../../slices/apiSlice/attendanceAllSlice"
|
|||||||
import { hasUserPermission } from "../../utils/authUtils";
|
import { hasUserPermission } from "../../utils/authUtils";
|
||||||
import { useHasUserPermission } from "../../hooks/useHasUserPermission";
|
import { useHasUserPermission } from "../../hooks/useHasUserPermission";
|
||||||
import { REGULARIZE_ATTENDANCE } from "../../utils/constants";
|
import { REGULARIZE_ATTENDANCE } from "../../utils/constants";
|
||||||
|
import eventBus from "../../services/eventBus";
|
||||||
|
import AttendanceRepository from "../../repositories/AttendanceRepository";
|
||||||
|
|
||||||
const AttendancePage = () => {
|
const AttendancePage = () => {
|
||||||
const [activeTab, setActiveTab] = useState("all");
|
const [activeTab, setActiveTab] = useState("all");
|
||||||
@ -25,7 +28,11 @@ const AttendancePage = () => {
|
|||||||
const loginUser = getCachedProfileData();
|
const loginUser = getCachedProfileData();
|
||||||
var selectedProject = useSelector((store) => store.localVariables.projectId);
|
var selectedProject = useSelector((store) => store.localVariables.projectId);
|
||||||
// const { projects, loading: projectLoading } = useProjects();
|
// const { projects, loading: projectLoading } = useProjects();
|
||||||
const { attendance, loading: attLoading } = useAttendace(selectedProject);
|
const {
|
||||||
|
attendance,
|
||||||
|
loading: attLoading,
|
||||||
|
recall: attrecall,
|
||||||
|
} = useAttendace(selectedProject);
|
||||||
const [attendances, setAttendances] = useState();
|
const [attendances, setAttendances] = useState();
|
||||||
const [empRoles, setEmpRoles] = useState(null);
|
const [empRoles, setEmpRoles] = useState(null);
|
||||||
const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);
|
const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);
|
||||||
@ -39,6 +46,40 @@ const AttendancePage = () => {
|
|||||||
date: new Date().toLocaleDateString(),
|
date: new Date().toLocaleDateString(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const handler = useCallback(
|
||||||
|
(msg) => {
|
||||||
|
if (selectedProject == msg.projectId) {
|
||||||
|
const updatedAttendance = attendances.map((item) =>
|
||||||
|
item.employeeId === msg.response.employeeId
|
||||||
|
? { ...item, ...msg.response }
|
||||||
|
: item
|
||||||
|
);
|
||||||
|
cacheData("Attendance", {
|
||||||
|
data: updatedAttendance,
|
||||||
|
projectId: selectedProject,
|
||||||
|
});
|
||||||
|
setAttendances(updatedAttendance);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[selectedProject, attrecall]
|
||||||
|
);
|
||||||
|
|
||||||
|
const employeeHandler = useCallback(
|
||||||
|
(msg) => {
|
||||||
|
if (attendances.some((item) => item.employeeId == msg.employeeId)) {
|
||||||
|
AttendanceRepository.getAttendance(selectedProject)
|
||||||
|
.then((response) => {
|
||||||
|
cacheData("Attendance", { data: response.data, selectedProject });
|
||||||
|
setAttendances(response.data);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error(error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[selectedProject, attendances]
|
||||||
|
);
|
||||||
|
|
||||||
const getRole = (roleId) => {
|
const getRole = (roleId) => {
|
||||||
if (!empRoles) return "Unassigned";
|
if (!empRoles) return "Unassigned";
|
||||||
if (!roleId) return "Unassigned";
|
if (!roleId) return "Unassigned";
|
||||||
@ -112,9 +153,20 @@ const AttendancePage = () => {
|
|||||||
// )
|
// )
|
||||||
// : attendances;
|
// : attendances;
|
||||||
const filteredAttendance = ShowPending
|
const filteredAttendance = ShowPending
|
||||||
? attendances?.filter((att) => att?.checkInTime !== null && att?.checkOutTime === null)
|
? attendances?.filter(
|
||||||
|
(att) => att?.checkInTime !== null && att?.checkOutTime === null
|
||||||
|
)
|
||||||
: attendances;
|
: attendances;
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
eventBus.on("attendance", handler);
|
||||||
|
return () => eventBus.off("attendance", handler);
|
||||||
|
}, [handler]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
eventBus.on("employee", employeeHandler);
|
||||||
|
return () => eventBus.off("employee", employeeHandler);
|
||||||
|
}, [employeeHandler]);
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{isCreateModalOpen && modelConfig && (
|
{isCreateModalOpen && modelConfig && (
|
||||||
@ -213,15 +265,10 @@ const AttendancePage = () => {
|
|||||||
Regularization
|
Regularization
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
<div className="tab-content attedanceTabs py-0 px-1 px-sm-3">
|
<div className="tab-content attedanceTabs py-0 px-1 px-sm-3">
|
||||||
|
|
||||||
|
|
||||||
{activeTab === "all" && (
|
{activeTab === "all" && (
|
||||||
<>
|
<>
|
||||||
|
|
||||||
<div className="tab-pane fade show active py-0">
|
<div className="tab-pane fade show active py-0">
|
||||||
<Attendance
|
<Attendance
|
||||||
attendance={filteredAttendance}
|
attendance={filteredAttendance}
|
||||||
@ -231,8 +278,13 @@ const AttendancePage = () => {
|
|||||||
showOnlyCheckout={ShowPending}
|
showOnlyCheckout={ShowPending}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{!attLoading && filteredAttendance?.length === 0 && (
|
{!attLoading && filteredAttendance?.length === 0 && (
|
||||||
<p> {ShowPending ? "No Pending Available" : "No Employee assigned yet."} </p>
|
<p>
|
||||||
|
{" "}
|
||||||
|
{ShowPending
|
||||||
|
? "No Pending Available"
|
||||||
|
: "No Employee assigned yet."}{" "}
|
||||||
|
</p>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
@ -254,7 +306,7 @@ const AttendancePage = () => {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{attLoading && <span>Loading..</span>}
|
{attLoading && <span>Loading..</span>}
|
||||||
{!attLoading && !attendances && <span>Not Found</span>}
|
{!attLoading && !attendances && <span>Not Found</span>}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { useState, useEffect, useRef } from "react";
|
import React, { useState, useEffect, useRef, useCallback } from "react";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import showToast from "../../services/toastService";
|
import showToast from "../../services/toastService";
|
||||||
import { Link, NavLink, useNavigate } from "react-router-dom";
|
import { Link, NavLink, useNavigate } from "react-router-dom";
|
||||||
@ -23,6 +23,8 @@ import EmployeeRepository from "../../repositories/EmployeeRepository";
|
|||||||
import ManageEmployee from "../../components/Employee/ManageEmployee";
|
import ManageEmployee from "../../components/Employee/ManageEmployee";
|
||||||
import ConfirmModal from "../../components/common/ConfirmModal";
|
import ConfirmModal from "../../components/common/ConfirmModal";
|
||||||
import { useSelector } from "react-redux";
|
import { useSelector } from "react-redux";
|
||||||
|
import eventBus from "../../services/eventBus";
|
||||||
|
import { newlineChars } from "pdf-lib";
|
||||||
|
|
||||||
const EmployeeList = () => {
|
const EmployeeList = () => {
|
||||||
const selectedProjectId = useSelector((store) => store.localVariables.projectId);
|
const selectedProjectId = useSelector((store) => store.localVariables.projectId);
|
||||||
@ -202,7 +204,6 @@ const EmployeeList = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleOpenDelete = (employee) => {
|
const handleOpenDelete = (employee) => {
|
||||||
console.log(employee);
|
|
||||||
setSelectedEmpFordelete(employee);
|
setSelectedEmpFordelete(employee);
|
||||||
setIsDeleteModalOpen(true);
|
setIsDeleteModalOpen(true);
|
||||||
};
|
};
|
||||||
@ -218,6 +219,20 @@ const EmployeeList = () => {
|
|||||||
setSelectedProject(selectedProjectId || "");
|
setSelectedProject(selectedProjectId || "");
|
||||||
}, [selectedProjectId]);
|
}, [selectedProjectId]);
|
||||||
|
|
||||||
|
const handler = useCallback(
|
||||||
|
(msg) => {
|
||||||
|
if(employees.some((item) => item.id == msg.employeeId)){
|
||||||
|
setEmployeeList([]);
|
||||||
|
recallEmployeeData(showInactive);
|
||||||
|
}
|
||||||
|
},[employees]
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
eventBus.on("employee",handler);
|
||||||
|
return () => eventBus.off("employee",handler)
|
||||||
|
},[handler])
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect, useCallback } from "react";
|
||||||
|
|
||||||
import ActivityTimeline from "../../components/Project/ActivityTimeline";
|
import ActivityTimeline from "../../components/Project/ActivityTimeline";
|
||||||
import ProjectOverview from "../../components/Project/ProjectOverview";
|
import ProjectOverview from "../../components/Project/ProjectOverview";
|
||||||
@ -11,7 +11,7 @@ import ProjectInfra from "../../components/Project/ProjectInfra";
|
|||||||
import Loader from "../../components/common/Loader";
|
import Loader from "../../components/common/Loader";
|
||||||
import WorkPlan from "../../components/Project/WorkPlan";
|
import WorkPlan from "../../components/Project/WorkPlan";
|
||||||
import Breadcrumb from "../../components/common/Breadcrumb";
|
import Breadcrumb from "../../components/common/Breadcrumb";
|
||||||
import { cacheData, getCachedData } from "../../slices/apiDataManager";
|
import { cacheData, clearCacheKey, getCachedData } from "../../slices/apiDataManager";
|
||||||
import ProjectRepository from "../../repositories/ProjectRepository";
|
import ProjectRepository from "../../repositories/ProjectRepository";
|
||||||
import { ActivityeRepository } from "../../repositories/MastersRepository";
|
import { ActivityeRepository } from "../../repositories/MastersRepository";
|
||||||
import "./ProjectDetails.css";
|
import "./ProjectDetails.css";
|
||||||
@ -23,6 +23,7 @@ import { useDispatch } from "react-redux";
|
|||||||
import { setProjectId } from "../../slices/localVariablesSlice";
|
import { setProjectId } from "../../slices/localVariablesSlice";
|
||||||
import { ComingSoonPage } from "../Misc/ComingSoonPage";
|
import { ComingSoonPage } from "../Misc/ComingSoonPage";
|
||||||
import Directory from "../Directory/Directory";
|
import Directory from "../Directory/Directory";
|
||||||
|
import eventBus from "../../services/eventBus";
|
||||||
|
|
||||||
const ProjectDetails = () => {
|
const ProjectDetails = () => {
|
||||||
let { projectId } = useParams();
|
let { projectId } = useParams();
|
||||||
@ -121,7 +122,7 @@ const ProjectDetails = () => {
|
|||||||
case "directory": {
|
case "directory": {
|
||||||
return (
|
return (
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<Directory IsPage={ false} prefernceContacts={projectDetails.id} />
|
<Directory IsPage={false} prefernceContacts={projectDetails.id} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -137,6 +138,31 @@ const ProjectDetails = () => {
|
|||||||
setProjectDetails(projects_Details);
|
setProjectDetails(projects_Details);
|
||||||
}, [projects_Details, projectId]);
|
}, [projects_Details, projectId]);
|
||||||
|
|
||||||
|
const handler = useCallback(
|
||||||
|
(msg) => {
|
||||||
|
if (msg.keyword === "Update_Project" && project.id === msg.response.id) {
|
||||||
|
clearCacheKey("projectInfo")
|
||||||
|
ProjectRepository.getProjectByprojectId(projectId)
|
||||||
|
.then((response) => {
|
||||||
|
setProjectDetails(response.data);
|
||||||
|
setProject(response.data);
|
||||||
|
cacheData("projectInfo", { projectId, data: response.data });
|
||||||
|
setLoading(false);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error(error);
|
||||||
|
setError("Failed to fetch data.");
|
||||||
|
setLoading(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[project,handleDataChange]
|
||||||
|
);
|
||||||
|
useEffect(() => {
|
||||||
|
eventBus.on("project", handler);
|
||||||
|
return () => eventBus.off("project", handler);
|
||||||
|
}, [handler]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{}
|
{}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect, useCallback } from "react";
|
||||||
import ProjectCard from "../../components/Project/ProjectCard";
|
import ProjectCard from "../../components/Project/ProjectCard";
|
||||||
import ManageProjectInfo from "../../components/Project/ManageProjectInfo";
|
import ManageProjectInfo from "../../components/Project/ManageProjectInfo";
|
||||||
import Breadcrumb from "../../components/common/Breadcrumb";
|
import Breadcrumb from "../../components/common/Breadcrumb";
|
||||||
@ -6,11 +6,14 @@ import ProjectRepository from "../../repositories/ProjectRepository";
|
|||||||
import { useProjects } from "../../hooks/useProjects";
|
import { useProjects } from "../../hooks/useProjects";
|
||||||
import { useDispatch } from "react-redux";
|
import { useDispatch } from "react-redux";
|
||||||
import showToast from "../../services/toastService";
|
import showToast from "../../services/toastService";
|
||||||
import { getCachedData, cacheData } from "../../slices/apiDataManager";
|
import { getCachedData, cacheData, clearCacheKey } from "../../slices/apiDataManager";
|
||||||
import { useHasUserPermission } from "../../hooks/useHasUserPermission";
|
import { useHasUserPermission } from "../../hooks/useHasUserPermission";
|
||||||
import { useProfile } from "../../hooks/useProfile";
|
import { useProfile } from "../../hooks/useProfile";
|
||||||
import { ITEMS_PER_PAGE, MANAGE_PROJECT } from "../../utils/constants";
|
import { ITEMS_PER_PAGE, MANAGE_PROJECT } from "../../utils/constants";
|
||||||
import ProjectListView from "./ProjectListView";
|
import ProjectListView from "./ProjectListView";
|
||||||
|
import eventBus from "../../services/eventBus";
|
||||||
|
import { clearApiCacheKey } from "../../slices/apiCacheSlice";
|
||||||
|
import { defaultCheckBoxAppearanceProvider } from "pdf-lib";
|
||||||
|
|
||||||
const ProjectList = () => {
|
const ProjectList = () => {
|
||||||
const { profile: loginUser } = useProfile();
|
const { profile: loginUser } = useProfile();
|
||||||
@ -37,7 +40,7 @@ const ProjectList = () => {
|
|||||||
const handleShow = () => setShowModal(true);
|
const handleShow = () => setShowModal(true);
|
||||||
const handleClose = () => setShowModal(false);
|
const handleClose = () => setShowModal(false);
|
||||||
|
|
||||||
const sortingProject = (projects) =>{
|
const sortingProject = (projects) => {
|
||||||
if (!loading && Array.isArray(projects)) {
|
if (!loading && Array.isArray(projects)) {
|
||||||
const grouped = {};
|
const grouped = {};
|
||||||
projects.forEach((project) => {
|
projects.forEach((project) => {
|
||||||
@ -53,13 +56,12 @@ const ProjectList = () => {
|
|||||||
a.name.toLowerCase()?.localeCompare(b.name.toLowerCase())
|
a.name.toLowerCase()?.localeCompare(b.name.toLowerCase())
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
setProjectList(sortedGrouped);
|
setProjectList(sortedGrouped);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
sortingProject(projects)
|
sortingProject(projects);
|
||||||
}, [projects, loginUser?.projects, loading]);
|
}, [projects, loginUser?.projects, loading]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -70,16 +72,16 @@ const ProjectList = () => {
|
|||||||
}
|
}
|
||||||
}, [loginUser, HasManageProjectPermission]);
|
}, [loginUser, HasManageProjectPermission]);
|
||||||
|
|
||||||
const handleSubmitForm = (newProject,setloading,reset) => {
|
const handleSubmitForm = (newProject, setloading, reset) => {
|
||||||
ProjectRepository.manageProject(newProject)
|
ProjectRepository.manageProject(newProject)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
const cachedProjects = getCachedData("projectslist") || [];
|
const cachedProjects = getCachedData("projectslist") || [];
|
||||||
const updatedProjects = [...cachedProjects, response.data];
|
const updatedProjects = [...cachedProjects, response.data];
|
||||||
cacheData("projectslist", updatedProjects);
|
cacheData("projectslist", updatedProjects);
|
||||||
setProjectList( ( prev ) => [ ...prev, response.data ] );
|
setProjectList((prev) => [...prev, response.data]);
|
||||||
setloading( false )
|
setloading(false);
|
||||||
reset()
|
reset();
|
||||||
sortingProject(getCachedData("projectslist"))
|
sortingProject(getCachedData("projectslist"));
|
||||||
showToast("Project Created successfully.", "success");
|
showToast("Project Created successfully.", "success");
|
||||||
setShowModal(false);
|
setShowModal(false);
|
||||||
})
|
})
|
||||||
@ -123,7 +125,6 @@ const ProjectList = () => {
|
|||||||
indexOfLastItem
|
indexOfLastItem
|
||||||
);
|
);
|
||||||
const totalPages = Math.ceil(filteredProjects.length / itemsPerPage);
|
const totalPages = Math.ceil(filteredProjects.length / itemsPerPage);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const tooltipTriggerList = Array.from(
|
const tooltipTriggerList = Array.from(
|
||||||
document.querySelectorAll('[data-bs-toggle="tooltip"]')
|
document.querySelectorAll('[data-bs-toggle="tooltip"]')
|
||||||
@ -131,6 +132,52 @@ const ProjectList = () => {
|
|||||||
tooltipTriggerList.forEach((el) => new bootstrap.Tooltip(el));
|
tooltipTriggerList.forEach((el) => new bootstrap.Tooltip(el));
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const handler = useCallback(
|
||||||
|
async (msg) => {
|
||||||
|
if (HasManageProject && msg.keyword === "Create_Project") {
|
||||||
|
const updatedProjects = [...projectList, msg.response];
|
||||||
|
cacheData("projectslist", updatedProjects);
|
||||||
|
setProjectList(updatedProjects);
|
||||||
|
sortingProject(updatedProjects);
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
msg.keyword === "Update_Project" &&
|
||||||
|
projectList.some((item) => item.id === msg.response.id)
|
||||||
|
) {
|
||||||
|
ProjectRepository.getProjectList()
|
||||||
|
.then((response) => {
|
||||||
|
cacheData("projectslist", response?.data);
|
||||||
|
sortingProject(response?.data);
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
console.error(e)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[HasManageProject, projectList, sortingProject]
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
eventBus.on("project", handler);
|
||||||
|
return () => eventBus.off("project", handler);
|
||||||
|
}, [handler]);
|
||||||
|
|
||||||
|
const assignProjectHandler = useCallback(
|
||||||
|
async (data) => {
|
||||||
|
clearCacheKey("projectslist");
|
||||||
|
await refetch();
|
||||||
|
|
||||||
|
sortingProject(projects);
|
||||||
|
},
|
||||||
|
[refetch]
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
eventBus.on("assign_project_one", assignProjectHandler);
|
||||||
|
return () => eventBus.off("assign_project_one", assignProjectHandler);
|
||||||
|
}, [handler]);
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div
|
<div
|
||||||
@ -200,49 +247,48 @@ const ProjectList = () => {
|
|||||||
<i className="bx bx-list-ul bx-sm"></i>
|
<i className="bx bx-list-ul bx-sm"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="dropdown ms-3">
|
<div className="dropdown ms-3">
|
||||||
<a
|
<a
|
||||||
className="dropdown-toggle hide-arrow cursor-pointer"
|
className="dropdown-toggle hide-arrow cursor-pointer"
|
||||||
data-bs-toggle="dropdown"
|
data-bs-toggle="dropdown"
|
||||||
aria-expanded="false"
|
aria-expanded="false"
|
||||||
>
|
>
|
||||||
<i className="bx bx-filter bx-lg"></i>
|
<i className="bx bx-filter bx-lg"></i>
|
||||||
</a>
|
</a>
|
||||||
<ul className="dropdown-menu p-2 text-capitalize">
|
<ul className="dropdown-menu p-2 text-capitalize">
|
||||||
{[
|
{[
|
||||||
{
|
{
|
||||||
id: "b74da4c2-d07e-46f2-9919-e75e49b12731",
|
id: "b74da4c2-d07e-46f2-9919-e75e49b12731",
|
||||||
label: "Active",
|
label: "Active",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "603e994b-a27f-4e5d-a251-f3d69b0498ba",
|
id: "603e994b-a27f-4e5d-a251-f3d69b0498ba",
|
||||||
label: "On Hold",
|
label: "On Hold",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "ef1c356e-0fe0-42df-a5d3-8daee355492d",
|
id: "ef1c356e-0fe0-42df-a5d3-8daee355492d",
|
||||||
label: "Inactive",
|
label: "Inactive",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "33deaef9-9af1-4f2a-b443-681ea0d04f81",
|
id: "33deaef9-9af1-4f2a-b443-681ea0d04f81",
|
||||||
label: "Completed",
|
label: "Completed",
|
||||||
},
|
},
|
||||||
].map(({ id, label }) => (
|
].map(({ id, label }) => (
|
||||||
<li key={id}>
|
<li key={id}>
|
||||||
<div className="form-check">
|
<div className="form-check">
|
||||||
<input
|
<input
|
||||||
className="form-check-input "
|
className="form-check-input "
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
checked={selectedStatuses.includes(id)}
|
checked={selectedStatuses.includes(id)}
|
||||||
onChange={() => handleStatusChange(id)}
|
onChange={() => handleStatusChange(id)}
|
||||||
/>
|
/>
|
||||||
<label className="form-check-label">{label}</label>
|
<label className="form-check-label">{label}</label>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
@ -341,7 +387,11 @@ const ProjectList = () => {
|
|||||||
</tr>
|
</tr>
|
||||||
) : (
|
) : (
|
||||||
currentItems.map((project) => (
|
currentItems.map((project) => (
|
||||||
<ProjectListView key={project.id} projectData={project} recall={sortingProject} />
|
<ProjectListView
|
||||||
|
key={project.id}
|
||||||
|
projectData={project}
|
||||||
|
recall={sortingProject}
|
||||||
|
/>
|
||||||
))
|
))
|
||||||
)}
|
)}
|
||||||
</tbody>
|
</tbody>
|
||||||
@ -349,7 +399,11 @@ const ProjectList = () => {
|
|||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
currentItems.map((project) => (
|
currentItems.map((project) => (
|
||||||
<ProjectCard key={project.id} projectData={project} recall={sortingProject} />
|
<ProjectCard
|
||||||
|
key={project.id}
|
||||||
|
projectData={project}
|
||||||
|
recall={sortingProject}
|
||||||
|
/>
|
||||||
))
|
))
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
@ -21,6 +21,9 @@ const ProjectListView = ({ projectData, recall }) => {
|
|||||||
const [showModal, setShowModal] = useState(false);
|
const [showModal, setShowModal] = useState(false);
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const ManageProject = useHasUserPermission(MANAGE_PROJECT);
|
const ManageProject = useHasUserPermission(MANAGE_PROJECT);
|
||||||
|
useEffect(()=>{
|
||||||
|
setProjectInfo(projectData);
|
||||||
|
},[projectData])
|
||||||
|
|
||||||
const handleShow = async () => {
|
const handleShow = async () => {
|
||||||
try {
|
try {
|
||||||
|
5
src/services/eventBus.js
Normal file
5
src/services/eventBus.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import EventEmitter from 'eventemitter3';
|
||||||
|
|
||||||
|
const eventBus = new EventEmitter();
|
||||||
|
|
||||||
|
export default eventBus;
|
106
src/services/signalRService.js
Normal file
106
src/services/signalRService.js
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
import * as signalR from "@microsoft/signalr";
|
||||||
|
import {
|
||||||
|
cacheData,
|
||||||
|
clearCacheKey,
|
||||||
|
getCachedData,
|
||||||
|
} from "../slices/apiDataManager";
|
||||||
|
import showToast from "./toastService";
|
||||||
|
import eventBus from "./eventBus";
|
||||||
|
import { useSelector } from "react-redux";
|
||||||
|
import { clearApiCacheKey } from "../slices/apiCacheSlice";
|
||||||
|
const base_Url = process.env.VITE_BASE_URL;
|
||||||
|
// const base_Url = "https://devapi.marcoaiot.com";
|
||||||
|
let connection = null;
|
||||||
|
|
||||||
|
const targetPath = "";
|
||||||
|
|
||||||
|
export function startSignalR(loggedUser) {
|
||||||
|
var jwtToken = localStorage.getItem("jwtToken");
|
||||||
|
connection = new signalR.HubConnectionBuilder()
|
||||||
|
.withUrl(`${base_Url}/hubs/marco`, {
|
||||||
|
accessTokenFactory: () => jwtToken,
|
||||||
|
transport: signalR.HttpTransportType.LongPolling,
|
||||||
|
withCredentials: false,
|
||||||
|
})
|
||||||
|
.withAutomaticReconnect()
|
||||||
|
.build();
|
||||||
|
const todayDate = new Date();
|
||||||
|
const today = new Date(
|
||||||
|
Date.UTC(todayDate.getFullYear(), todayDate.getMonth(), todayDate.getDate())
|
||||||
|
)
|
||||||
|
.toISOString()
|
||||||
|
.split("T")[0];
|
||||||
|
connection.on("NotificationEventHandler", (data) => {
|
||||||
|
if (data.loggedInUserId != loggedUser?.employeeInfo.id) {
|
||||||
|
// console.log("Notification received:", data);
|
||||||
|
// if action taken on attendance module
|
||||||
|
if (data.keyword == "Attendance") {
|
||||||
|
const checkIn = data.response.checkInTime.substring(0, 10);
|
||||||
|
if (today === checkIn) {
|
||||||
|
eventBus.emit("attendance", data);
|
||||||
|
}
|
||||||
|
var onlyDate = Number(checkIn.substring(8, 10));
|
||||||
|
|
||||||
|
var afterTwoDay =
|
||||||
|
checkIn.substring(0, 8) + (onlyDate + 2).toString().padStart(2, "0");
|
||||||
|
if (
|
||||||
|
afterTwoDay <= today &&
|
||||||
|
(data.response.activity == 4 || data.response.activity == 5)
|
||||||
|
) {
|
||||||
|
eventBus.emit("regularization", data);
|
||||||
|
}
|
||||||
|
eventBus.emit("attendance_log", data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if create or update project
|
||||||
|
if (
|
||||||
|
data.keyword == "Create_Project" ||
|
||||||
|
data.keyword == "Update_Project"
|
||||||
|
) {
|
||||||
|
clearCacheKey("projectslist");
|
||||||
|
eventBus.emit("project", data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if assign or deassign employee to any project
|
||||||
|
if (data.keyword == "Assign_Project") {
|
||||||
|
if (
|
||||||
|
data.employeeList.some((item) => item === loggedUser?.employeeInfo.id)
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
cacheData("hasReceived", false);
|
||||||
|
eventBus.emit("assign_project_one", data);
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Error in cacheData:", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
eventBus.emit("assign_project_all", data);
|
||||||
|
}
|
||||||
|
// if created or updated infra
|
||||||
|
if (data.keyword == "Infra") {
|
||||||
|
clearCacheKey("projectInfo");
|
||||||
|
eventBus.emit("infra", data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if created or updated Employee
|
||||||
|
if (data.keyword == "Employee") {
|
||||||
|
clearCacheKey("employeeListByProject");
|
||||||
|
clearCacheKey("allEmployeeList");
|
||||||
|
clearCacheKey("allInactiveEmployeeList");
|
||||||
|
clearCacheKey("employeeProfile");
|
||||||
|
clearCacheKey("Attendance");
|
||||||
|
clearCacheKey("regularizedList")
|
||||||
|
clearCacheKey("AttendanceLogs")
|
||||||
|
eventBus.emit("employee", data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
connection
|
||||||
|
.start()
|
||||||
|
.then(() => console.log("SignalR connected"))
|
||||||
|
.catch((err) => console.error("SignalR error:", err));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function stopSignalR() {
|
||||||
|
if (connection) connection.stop();
|
||||||
|
}
|
@ -2,6 +2,7 @@ import axios from "axios";
|
|||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import axiosRetry from "axios-retry";
|
import axiosRetry from "axios-retry";
|
||||||
import showToast from "../services/toastService";
|
import showToast from "../services/toastService";
|
||||||
|
import { startSignalR, stopSignalR } from "../services/signalRService";
|
||||||
const base_Url = process.env.VITE_BASE_URL;
|
const base_Url = process.env.VITE_BASE_URL;
|
||||||
// const base_Url = "https://api.marcoaiot.com";
|
// const base_Url = "https://api.marcoaiot.com";
|
||||||
export const axiosClient = axios.create({
|
export const axiosClient = axios.create({
|
||||||
@ -69,6 +70,8 @@ axiosClient.interceptors.response.use(
|
|||||||
return Promise.reject(error);
|
return Promise.reject(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stopSignalR();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Refresh token
|
// Refresh token
|
||||||
const res = await axiosClient.post("/api/Auth/refresh-token", {
|
const res = await axiosClient.post("/api/Auth/refresh-token", {
|
||||||
@ -82,6 +85,7 @@ axiosClient.interceptors.response.use(
|
|||||||
localStorage.setItem("jwtToken", token);
|
localStorage.setItem("jwtToken", token);
|
||||||
localStorage.setItem("refreshToken", newRefreshToken);
|
localStorage.setItem("refreshToken", newRefreshToken);
|
||||||
|
|
||||||
|
startSignalR()
|
||||||
// Set Authorization header
|
// Set Authorization header
|
||||||
originalRequest.headers["Authorization"] = `Bearer ${token}`;
|
originalRequest.headers["Authorization"] = `Bearer ${token}`;
|
||||||
|
|
||||||
|
@ -4,8 +4,8 @@ export const getProjectStatusName = (statusId) => {
|
|||||||
return "Active";
|
return "Active";
|
||||||
case "603e994b-a27f-4e5d-a251-f3d69b0498ba":
|
case "603e994b-a27f-4e5d-a251-f3d69b0498ba":
|
||||||
return "On Hold";
|
return "On Hold";
|
||||||
// case 3:
|
case "cdad86aa-8a56-4ff4-b633-9c629057dfef":
|
||||||
// return "Suspended";
|
return "In Progress";
|
||||||
case "ef1c356e-0fe0-42df-a5d3-8daee355492d":
|
case "ef1c356e-0fe0-42df-a5d3-8daee355492d":
|
||||||
return "Inactive";
|
return "Inactive";
|
||||||
case "33deaef9-9af1-4f2a-b443-681ea0d04f81":
|
case "33deaef9-9af1-4f2a-b443-681ea0d04f81":
|
||||||
@ -23,8 +23,8 @@ export const getProjectStatusColor = (statusId) => {
|
|||||||
return "bg-label-info";
|
return "bg-label-info";
|
||||||
case "33deaef9-9af1-4f2a-b443-681ea0d04f81":
|
case "33deaef9-9af1-4f2a-b443-681ea0d04f81":
|
||||||
return "bg-label-secondary";
|
return "bg-label-secondary";
|
||||||
case 5:
|
case "cdad86aa-8a56-4ff4-b633-9c629057dfef":
|
||||||
return "bg-label-dark";
|
return "bg-label-success";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user