229 Commits

Author SHA1 Message Date
49ce97d394 Update sge-frontend/package.json 2025-12-14 22:01:39 +03:00
a7ba6fe3e4 Merge pull request 'test' (#13) from test into main
Reviewed-on: #13
2025-10-30 20:23:54 +03:00
7976d56552 Update sge-backend/src/main/java/com/sgs/SgsApplication.java
All checks were successful
sgeUpdated CI/CD / deploy (pull_request) Successful in 42s
2025-10-30 20:23:13 +03:00
e3536ea6a3 Update sge-backend/pom.xml 2025-10-30 20:20:53 +03:00
66aeed7fda Merge pull request 'Update sge-frontend/package.json' (#12) from test into main
Reviewed-on: #12
2025-10-30 20:12:13 +03:00
fcc5edcbe2 Update sge-frontend/package.json
All checks were successful
sgeUpdated CI/CD / deploy (pull_request) Successful in 3m23s
2025-10-30 20:11:53 +03:00
8f41ce3d51 Merge pull request 'Test branch' (#11) from test into main
Reviewed-on: #11
2025-10-30 20:11:09 +03:00
abdelbari
4ea1cfa9b4 Test branch
All checks were successful
sgeUpdated CI/CD / deploy (pull_request) Successful in 7s
2025-10-30 17:08:40 +00:00
68835f5919 Update sge-frontend/package.json 2025-10-30 19:46:20 +03:00
ee29ecd766 Update .gitea/workflows/sgeupdated.yml 2025-10-30 19:35:34 +03:00
f4dd4a9dce Merge pull request 'Update sge-frontend/package.json' (#4) from test into main
Reviewed-on: #4
2025-10-30 19:31:36 +03:00
853230e742 Update sge-frontend/package.json
All checks were successful
sgeUpdated CI/CD / deploy (pull_request) Successful in 3m20s
2025-10-30 19:30:40 +03:00
0a4462923e Update .gitea/workflows/sgeupdated.yml 2025-10-30 19:29:17 +03:00
7f56158c02 Merge pull request 'Test branch' (#3) from test into main
Reviewed-on: #3
2025-10-30 19:23:16 +03:00
1174707918 Update sge-frontend/src/views/DataSet/EmissionSource.js
All checks were successful
sgeUpdated CI/CD / deploy (pull_request) Successful in 3m4s
2025-10-30 19:21:22 +03:00
93cad886d6 Update .gitea/workflows/sgeupdated.yml 2025-10-30 19:20:19 +03:00
a15f249016 Test branch
Some checks failed
sgeUpdated CI/CD / deploy (pull_request) Failing after 45s
2025-10-30 16:05:38 +00:00
5c1f255c3f Merge pull request 'Update sge-backend/pom.xml' (#2) from omar/sgeUpdated:main into main
Reviewed-on: #2
2025-10-30 18:56:54 +03:00
453d35702c Update .gitea/workflows/sgeupdated.yml 2025-10-30 18:55:20 +03:00
cf08be1ddc Update sge-backend/pom.xml
Some checks failed
sgeUpdated CI/CD / deploy (pull_request) Failing after 5s
2025-10-30 18:54:48 +03:00
4a9b65cc30 Update .gitea/workflows/sgeupdated.yml
All checks were successful
sgeUpdated CI/CD / deploy (push) Successful in 7s
2025-10-30 18:46:25 +03:00
472a5daf09 Update sge-frontend/src/views/Communication.js
All checks were successful
sgeUpdated CI/CD / deploy (push) Successful in 2m51s
2025-10-28 19:00:41 +03:00
dcdc1bf43a Update sge-frontend/src/views/Areas/Areas.js 2025-10-28 18:59:54 +03:00
c9b5ebf80e Update sge-backend/pom.xml
All checks were successful
sgeUpdated CI/CD / deploy (push) Successful in 58s
2025-10-28 18:56:54 +03:00
caa0549983 Update sge-frontend/package.json
All checks were successful
sgeUpdated CI/CD / deploy (push) Successful in 1m31s
2025-10-28 18:46:42 +03:00
4400572a45 Update sge-frontend/package.json
All checks were successful
sgeUpdated CI/CD / deploy (push) Successful in 2m54s
2025-10-28 18:41:04 +03:00
04ee05a96b Update sge-frontend/package.json
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 13s
2025-10-28 18:20:22 +03:00
7580bf7cdb Update sge-frontend/README.md
All checks were successful
sgeUpdated CI/CD / deploy (push) Successful in 7s
2025-10-28 18:06:28 +03:00
0d017c0a4b Update sge-frontend/package.json
All checks were successful
sgeUpdated CI/CD / deploy (push) Successful in 2m46s
2025-10-28 18:02:59 +03:00
1eeb91c91c Update sge-backend/README.md 2025-10-28 18:02:18 +03:00
cd18444b08 Update sge-backend/pom.xml 2025-10-28 18:01:05 +03:00
1354d01878 Update sge-frontend/README.md 2025-10-28 17:14:39 +03:00
9856c1f9aa Update sge-frontend/package.json 2025-10-28 17:03:05 +03:00
b1ea7bf736 Update sge-frontend/README.md
Some checks failed
sgeUpdated CI/CD / deploy (push) Has been cancelled
2025-10-28 16:42:50 +03:00
8b82b44591 Update sge-backend/pom.xml
Some checks failed
sgeUpdated CI/CD / deploy (push) Has been cancelled
2025-10-28 16:41:26 +03:00
5c534314df Update sge-backend/README.md
Some checks failed
sgeUpdated CI/CD / deploy (push) Has been cancelled
2025-10-28 16:40:53 +03:00
dde5fece3b Update sge-backend/README.md
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 38s
2025-10-28 16:31:43 +03:00
f3b893f05c Update sge-backend/README.md
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 38s
2025-10-28 16:19:26 +03:00
08e8badae2 Update sge-backend/README.md
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 7s
2025-10-28 16:02:04 +03:00
dd1083db82 Update .gitea/workflows/sgeupdated.yml
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 12s
2025-10-28 15:33:14 +03:00
fad8037371 Update sgeupdated pipeline v25+
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 7s
2025-10-28 15:04:50 +03:00
61faf1bf46 Update sge-backend/README.md
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 7s
2025-10-27 18:39:50 +03:00
230c4bcb6e Update sge-backend/README.md
Some checks failed
sgeUpdated CI/CD / deploy (push) Has been cancelled
2025-10-27 17:53:46 +03:00
cbe2660080 Update sgeupdated pipeline v25
All checks were successful
sgeUpdated CI/CD / deploy (push) Successful in 9s
New script to call the deploy.sh file in the server
2025-10-27 17:29:31 +03:00
cf38f431a8 Update sge-frontend/src/views/Communication.js
Some checks failed
sgeUpdated CI/CD / deploy (push) Has been cancelled
2025-10-25 23:53:46 +03:00
f585763563 Update .gitea/workflows/sgeupdated.yml
All checks were successful
sgeUpdated CI/CD / deploy (push) Successful in 7s
2025-10-25 23:52:38 +03:00
7bee15a901 Update sge-frontend/README.md
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 9s
2025-10-24 18:04:13 +03:00
1ae3d76781 Update sgeupdated pipeline v22-+
All checks were successful
sgeUpdated CI/CD / deploy (push) Successful in 6s
2025-10-24 18:03:14 +03:00
53d5bf2e77 Update sge-frontend/README.md
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 3m1s
2025-10-24 17:57:15 +03:00
60e50dc9e8 Update .gitea/workflows/sgeupdated.yml
All checks were successful
sgeUpdated CI/CD / deploy (push) Successful in 7s
2025-10-24 17:50:36 +03:00
aaf116ca71 Update .gitea/workflows/sgeupdated.yml
Some checks failed
sgeUpdated CI/CD / deploy (push) Has been cancelled
2025-10-24 17:47:44 +03:00
061c0cb376 Update sgeupdated pipeline v22-
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 9s
2025-10-24 17:46:55 +03:00
bd155fadb2 Update sge-backend/README.md
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 42s
2025-10-24 17:32:23 +03:00
11541714f5 Update sge-frontend/README.md
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 3m56s
2025-10-24 17:07:27 +03:00
91559134cd Update sge-backend/README.md
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 49s
2025-10-24 17:03:16 +03:00
d26ca12e0c Update sgeupdated pipeline v22-
All checks were successful
sgeUpdated CI/CD / deploy (push) Successful in 7s
2025-10-24 15:35:57 +03:00
18c8c49a3d Update sge-frontend/README.md
All checks were successful
sgeUpdated CI/CD / deploy (push) Successful in 7s
2025-10-24 15:28:43 +03:00
97253a54eb Update sge-backend/README.md
All checks were successful
sgeUpdated CI/CD / deploy (push) Successful in 8s
2025-10-24 15:26:53 +03:00
f411f44006 Update sgeupdated pipeline v22
All checks were successful
sgeUpdated CI/CD / deploy (push) Successful in 8s
2025-10-24 15:21:53 +03:00
f4f4fb976b Update sgeupdated pipeline v22+
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 16s
2025-10-24 15:19:57 +03:00
385eda2132 Update sgeupdated pipeline v22
All checks were successful
sgeUpdated CI/CD / deploy (push) Successful in 6s
2025-10-24 15:13:23 +03:00
23a3d8252e Update sge-backend/pom.xml
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 26s
2025-10-24 15:11:40 +03:00
eeda227698 Update sgeupdated pipeline v24
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 26s
2025-10-24 15:09:18 +03:00
871bcf9651 Update sgeupdated pipeline v23++++
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 22s
2025-10-23 13:04:06 +03:00
614cbe8b04 Update sgeupdated pipeline v23+++
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 9s
2025-10-23 13:01:17 +03:00
ce19adb1a0 Update sgeupdated pipeline v23++
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 15s
2025-10-23 12:56:52 +03:00
5471db463f Update sgeupdated pipeline v23+
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 21s
2025-10-23 12:47:17 +03:00
845417ee49 Update sgeupdated pipeline v23
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 20s
2025-10-23 12:41:49 +03:00
1c12ac1e16 Update sge-frontend/package.json
All checks were successful
sgeUpdated CI/CD / deploy (push) Successful in 7s
2025-10-23 12:08:16 +03:00
eb2ec01d28 Update sgeupdated pipeline v22
All checks were successful
sgeUpdated CI/CD / deploy (push) Successful in 7s
new script for gitea
2025-10-23 12:06:40 +03:00
4d40015fd1 Update sge-frontend/package.json
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 21s
2025-10-22 19:24:33 +03:00
c55f5ce7d1 Update sge-frontend/package.json
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 21s
2025-10-22 19:17:57 +03:00
07a8973b92 Update for pipeline testing Back-end +
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 22s
2025-10-22 19:07:18 +03:00
54b47eee05 Update .gitea/workflows/sgeupdated.yml
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 21s
2025-10-22 18:46:53 +03:00
3f0550f9f2 Update .gitea/workflows/sgeupdated.yml
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 21s
2025-10-22 18:45:08 +03:00
6499c9471e Update .gitea/workflows/sgeupdated.yml
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 21s
2025-10-22 18:42:07 +03:00
71e507c21b Update .gitea/workflows/sgeupdated.yml
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 21s
2025-10-22 18:39:28 +03:00
737fd6da53 Update .gitea/workflows/sgeupdated.yml
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 22s
2025-10-22 18:34:24 +03:00
490f3b539e Update .gitea/workflows/sgeupdated.yml
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 21s
2025-10-22 18:32:24 +03:00
9c0c4c4828 Update .gitea/workflows/sgeupdated.yml
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 21s
2025-10-22 18:29:51 +03:00
b28a73b4ff Update .gitea/workflows/sgeupdated.yml
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 22s
2025-10-22 18:27:20 +03:00
f087b6eb88 Update .gitea/workflows/sgeupdated.yml
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 22s
2025-10-22 18:23:55 +03:00
d07932cc1e Update .gitea/workflows/sgeupdated.yml
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 22s
2025-10-22 18:21:17 +03:00
76d37d6038 Update .gitea/workflows/sgeupdated.yml
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 21s
2025-10-22 18:11:36 +03:00
50abcab358 Update sgeupdated pipeline v21++++++++
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 21s
Commented the backend section
2025-10-22 17:55:10 +03:00
445f9256a1 Update sgeupdated pipeline v21+++++++
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 23s
Commented the backend section
2025-10-22 17:53:16 +03:00
4d1a82fe92 Update for pipeline testing Front-end v099
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 2m33s
2025-10-22 17:12:00 +03:00
6d6e935b52 Update sgeupdated pipeline v21++++++
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 22s
commenting the frontend dependencies installation
2025-10-22 17:10:24 +03:00
a51a81ce7c Update sgeupdated pipeline v21+++++
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 2m30s
Paused the concurrency check temporally
2025-10-22 16:05:33 +03:00
3b6000bc40 Update sgeupdated pipeline v21++++
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 22s
2025-10-22 15:52:38 +03:00
78ed73acc6 Update .gitea/workflows/sgeupdated.yml
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 2m29s
2025-10-22 15:47:39 +03:00
7f8a7b1bf8 Update sgeupdated pipeline v21++++
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 2m31s
2025-10-22 15:39:57 +03:00
8c6e37ad72 Update sgeupdated pipeline v21+++
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 21s
2025-10-22 15:38:04 +03:00
85151e536d Update sgeupdated pipeline v21++
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 21s
2025-10-22 15:08:02 +03:00
573db7fee9 Update sgeupdated pipeline v21+
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 21s
2025-10-22 14:49:07 +03:00
a11f9614ed Update sgeupdated pipeline v21
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 20s
new condition to be added
2025-10-22 14:29:27 +03:00
02bd570573 Update sge-backend/pom.xml
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 3m19s
2025-10-21 16:12:15 +03:00
5da26152a9 update to sgeupdated pipeline v20++++++
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 23s
2025-09-05 23:07:35 +03:00
4f4c2e2ce5 Update .gitea/workflows/sgeupdated.yml
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 1m5s
2025-09-05 23:01:04 +03:00
79ddbf2207 Update docker-compose.yml
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 45s
2025-09-05 22:59:28 +03:00
23d9e65a7f update to sgeupdated pipeline v20+++++
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 51s
2025-09-05 22:55:07 +03:00
c8f9abe5e9 update to sgeupdated pipeline v20+++++
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 56s
changing in npm installation
2025-09-05 22:49:34 +03:00
fa96969bc7 update to sgeupdated pipeline v20++++
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 16s
2025-09-05 22:37:40 +03:00
dc67f75027 Update sge-frontend/nginx.conf
All checks were successful
sgeUpdated CI/CD / deploy (push) Successful in 9m42s
2025-09-05 22:01:33 +03:00
e22c880673 Update sge-backend/Dockerfile
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 16s
2025-09-05 21:57:44 +03:00
b37ed8797b update to sgeupdated pipeline v20+++
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 10m22s
2025-09-01 05:14:58 +03:00
04ed88e45e Update for pipeline testing Back-end
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 21s
2025-09-01 05:11:10 +03:00
5f8de8105b update to sgeupdated pipeline v21
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 21s
2025-09-01 05:09:20 +03:00
8fb923a4db Update for pipeline testing Back-end
Some checks failed
sgeUpdated CI/CD / deploy (push) Has been cancelled
2025-09-01 05:01:57 +03:00
a088889a67 update to sgeupdated pipeline v20+++
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 10m21s
2025-09-01 04:50:38 +03:00
b3de688265 update to sgeupdated pipeline v20++
Some checks failed
sgeUpdated CI/CD / deploy (push) Has been cancelled
2025-09-01 04:41:12 +03:00
080924f788 update to sgeupdated pipeline v20+
Some checks failed
sgeUpdated CI/CD / deploy (push) Has been cancelled
2025-09-01 03:57:59 +03:00
e43199f086 Update sge-frontend/nginx.conf
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 22s
2025-09-01 03:52:57 +03:00
49e2020455 update to sgeupdated pipeline v20
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 21s
2025-09-01 03:33:42 +03:00
876227286c Update for pipeline testing Front-end v00
All checks were successful
sgeUpdated CI/CD / deploy (push) Successful in 21s
2025-09-01 03:28:59 +03:00
af518cef20 Update for pipeline testing Back-end
All checks were successful
sgeUpdated CI/CD / deploy (push) Successful in 23s
2025-09-01 03:27:48 +03:00
2e5bf41ed9 update to sgeupdated pipeline v19
All checks were successful
sgeUpdated CI/CD / deploy (push) Successful in 22s
changes the concept of rebuilding
2025-09-01 03:26:26 +03:00
f61199cedb Update for pipeline testing Front-end
All checks were successful
sgeUpdated CI/CD / deploy (push) Successful in 22s
2025-09-01 03:06:55 +03:00
5001a44406 Update for pipeline testing
All checks were successful
sgeUpdated CI/CD / deploy (push) Successful in 2m15s
2025-09-01 03:03:47 +03:00
87487510ce update to sgeupdated pipeline v18
All checks were successful
sgeUpdated CI/CD / deploy (push) Successful in 23s
added some feature to avoid failing when nothing is changed
2025-09-01 03:02:23 +03:00
547ade53ae update to sgeupdated pipeline v17
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 22s
2025-09-01 02:57:34 +03:00
95afe7b877 Back to sgeupdated pipeline v16
All checks were successful
sgeUpdated CI/CD / deploy (push) Successful in 21s
2025-09-01 02:46:07 +03:00
ae0e112572 Delete smoke file
All checks were successful
SgeUpdated Deploy / deploy-frontend (push) Has been skipped
SgeUpdated Deploy / deploy-backend (push) Has been skipped
2025-09-01 02:41:02 +03:00
b35eac74a1 Update sgeupdated pipeline v17
All checks were successful
sgeUpdated Smoke Test / smoke-test (push) Successful in 6s
SgeUpdated Deploy / deploy-frontend (push) Has been skipped
SgeUpdated Deploy / deploy-backend (push) Has been skipped
a clone of the aypos yml file to test it
2025-09-01 02:40:20 +03:00
20aabd605c Update for pipeline testing Front-end
All checks were successful
sgeUpdated CI/CD / deploy (push) Successful in 20s
sgeUpdated Smoke Test / smoke-test (push) Successful in 6s
2025-08-30 21:12:44 +03:00
517d4d499b Update for pipeline testing
Some checks failed
sgeUpdated CI/CD / deploy (push) Successful in 21s
sgeUpdated Smoke Test / smoke-test (push) Has been cancelled
2025-08-30 21:12:22 +03:00
1aa745ebf5 Update sgeupdated pipeline v16
All checks were successful
sgeUpdated Smoke Test / smoke-test (push) Successful in 6s
sgeUpdated CI/CD / deploy (push) Successful in 22s
2025-08-30 21:11:03 +03:00
88a312d37c Update sgeupdated pipeline v15
All checks were successful
sgeUpdated CI/CD / deploy (push) Successful in 23s
sgeUpdated Smoke Test / smoke-test (push) Successful in 6s
forgot to add the dependencies installation
2025-08-30 21:04:54 +03:00
b1019b21cf Update for pipeline testing Front-end
All checks were successful
sgeUpdated CI/CD / deploy (push) Successful in 20s
sgeUpdated Smoke Test / smoke-test (push) Successful in 6s
2025-08-30 21:02:37 +03:00
57c28e4a90 Update for pipeline testing
Some checks failed
sgeUpdated Smoke Test / smoke-test (push) Has been cancelled
sgeUpdated CI/CD / deploy (push) Successful in 22s
2025-08-30 21:02:19 +03:00
b1cf711420 Update sgeupdated pipeline v14
All checks were successful
sgeUpdated Smoke Test / smoke-test (push) Successful in 6s
sgeUpdated CI/CD / deploy (push) Successful in 21s
multiple changes applied to make the workflows works over ssh
2025-08-30 20:58:45 +03:00
1d6b026710 Update for pipeline testing
All checks were successful
sgeUpdated Smoke Test / smoke-test (push) Successful in 6s
sgeUpdated CI/CD / deploy (push) Successful in 21s
2025-08-30 20:21:33 +03:00
02e4993c2c Update for pipeline testing Front-end
All checks were successful
sgeUpdated Smoke Test / smoke-test (push) Successful in 6s
sgeUpdated CI/CD / deploy (push) Successful in 21s
2025-08-30 20:20:37 +03:00
be71b59a3e Update for pipeline testing Front-end
All checks were successful
sgeUpdated CI/CD / deploy (push) Successful in 22s
sgeUpdated Smoke Test / smoke-test (push) Successful in 6s
2025-08-30 20:11:43 +03:00
7e5761993b Update for pipeline testing Front-end
All checks were successful
sgeUpdated Smoke Test / smoke-test (push) Successful in 5s
sgeUpdated CI/CD / deploy (push) Successful in 20s
2025-08-30 04:20:34 +03:00
66bd7b5a68 Update for pipeline testing
All checks were successful
sgeUpdated Smoke Test / smoke-test (push) Successful in 21s
sgeUpdated CI/CD / deploy (push) Successful in 23s
2025-08-30 04:20:16 +03:00
206d8a2bbf Update sgeupdated pipeline v13
All checks were successful
sgeUpdated Smoke Test / smoke-test (push) Successful in 6s
sgeUpdated CI/CD / deploy (push) Successful in 23s
2025-08-30 04:14:36 +03:00
6fbca1c29a Update for pipeline testing Front-end
All checks were successful
sgeUpdated Smoke Test / smoke-test (push) Successful in 10s
sgeUpdated CI/CD / deploy (push) Successful in 22s
2025-08-30 03:41:56 +03:00
1f6b06260c Update for pipeline testing
All checks were successful
sgeUpdated Smoke Test / smoke-test (push) Successful in 6s
sgeUpdated CI/CD / deploy (push) Successful in 29s
2025-08-30 03:38:28 +03:00
b00a8e1bf1 Update Front-End after pipeline v10
All checks were successful
sgeUpdated CI/CD / deploy (push) Successful in 22s
sgeUpdated Smoke Test / smoke-test (push) Successful in 9s
2025-08-30 03:11:38 +03:00
0f01ddefe9 Update Back-End after pipeline v12
Some checks failed
sgeUpdated Smoke Test / smoke-test (push) Has been cancelled
sgeUpdated CI/CD / deploy (push) Has been cancelled
2025-08-30 03:11:13 +03:00
2116b0f28a Update Front-End after pipeline v9
All checks were successful
sgeUpdated Smoke Test / smoke-test (push) Successful in 5s
sgeUpdated CI/CD / deploy (push) Successful in 22s
2025-08-30 03:02:45 +03:00
5161286279 Update Back-End after pipeline v11
Some checks failed
sgeUpdated Smoke Test / smoke-test (push) Has been cancelled
sgeUpdated CI/CD / deploy (push) Successful in 22s
2025-08-30 03:02:19 +03:00
29963d5388 Update sgeupdated pipeline v12
All checks were successful
sgeUpdated Smoke Test / smoke-test (push) Successful in 7s
sgeUpdated CI/CD / deploy (push) Successful in 27s
2025-08-30 03:00:47 +03:00
990b98c171 Update sgeupdated pipeline v12
All checks were successful
sgeUpdated Smoke Test / smoke-test (push) Successful in 8s
2025-08-30 02:58:54 +03:00
f2d5182215 Update sgeupdated pipeline v12
All checks were successful
sgeUpdated Smoke Test / smoke-test (push) Successful in 6s
2025-08-30 02:57:42 +03:00
e9a361489e Update sgeupdated pipeline v12
All checks were successful
sgeUpdated Smoke Test / smoke-test (push) Successful in 6s
a new update that fixed the docker files problem, it deletes the old ones then builds the new accordingly
2025-08-30 02:56:08 +03:00
37873ad091 Update Dockerfile
All checks were successful
sgeUpdated Smoke Test / smoke-test (push) Successful in 5s
sgeUpdated CI/CD / deploy (push) Successful in 21s
2025-08-30 01:58:28 +03:00
cac67b815c Update Front-End after pipeline v8
All checks were successful
sgeUpdated CI/CD / deploy (push) Successful in 21s
sgeUpdated Smoke Test / smoke-test (push) Successful in 6s
2025-08-30 01:38:03 +03:00
28fc21e9f2 Update Back-End after pipeline v10
Some checks failed
sgeUpdated Smoke Test / smoke-test (push) Has been cancelled
sgeUpdated CI/CD / deploy (push) Has been cancelled
2025-08-30 01:37:40 +03:00
98a2515735 Update sgeupdated pipeline v11
All checks were successful
sgeUpdated Smoke Test / smoke-test (push) Successful in 6s
sgeUpdated CI/CD / deploy (push) Successful in 23s
2025-08-30 01:36:21 +03:00
4503d7c319 Update sgeupdated pipeline v11
All checks were successful
sgeUpdated Smoke Test / smoke-test (push) Successful in 6s
2025-08-30 01:33:48 +03:00
e2a1b6f940 Update sgeupdated pipeline v11
All checks were successful
sgeUpdated Smoke Test / smoke-test (push) Successful in 6s
2025-08-30 01:33:02 +03:00
d25a7975c7 Update sgeupdated pipeline v11
All checks were successful
sgeUpdated Smoke Test / smoke-test (push) Successful in 6s
2025-08-30 01:29:50 +03:00
926c6b0b66 Update sgeupdated pipeline v11
All checks were successful
sgeUpdated Smoke Test / smoke-test (push) Successful in 6s
2025-08-30 01:28:12 +03:00
986bec559b Update Front-End after pipeline v7
All checks were successful
sgeUpdated CI/CD / deploy (push) Successful in 21s
sgeUpdated Smoke Test / smoke-test (push) Successful in 6s
2025-08-30 01:14:28 +03:00
77d5c94cf7 Update Back-End after pipeline v9
Some checks failed
sgeUpdated CI/CD / deploy (push) Successful in 23s
sgeUpdated Smoke Test / smoke-test (push) Has been cancelled
2025-08-30 01:14:02 +03:00
75c2f7ff19 Update sgeupdated pipeline v10
All checks were successful
sgeUpdated Smoke Test / smoke-test (push) Successful in 6s
sgeUpdated CI/CD / deploy (push) Successful in 23s
new code updated changes in fornt-end and back-end structure
2025-08-30 01:09:38 +03:00
55577469de Update Front-End after pipeline v6
All checks were successful
sgeUpdated CI/CD / deploy (push) Successful in 21s
sgeUpdated Smoke Test / smoke-test (push) Successful in 6s
2025-08-30 01:02:15 +03:00
f50803f469 Update Back-End after pipeline v8
Some checks failed
sgeUpdated CI/CD / deploy (push) Successful in 22s
sgeUpdated Smoke Test / smoke-test (push) Has been cancelled
2025-08-30 01:01:47 +03:00
adce8cddd8 Update sgeupdated pipeline v9
All checks were successful
sgeUpdated Smoke Test / smoke-test (push) Successful in 6s
sgeUpdated CI/CD / deploy (push) Successful in 22s
2025-08-29 20:17:14 +03:00
c2ddc08802 Update Front-End after pipeline v5
All checks were successful
sgeUpdated CI/CD / deploy (push) Successful in 21s
sgeUpdated Smoke Test / smoke-test (push) Successful in 6s
2025-08-29 20:11:39 +03:00
2c79300663 Update Back-End after pipeline v7
Some checks failed
sgeUpdated Smoke Test / smoke-test (push) Has been cancelled
sgeUpdated CI/CD / deploy (push) Has been cancelled
2025-08-29 20:11:17 +03:00
a6bb799caa Update sgeupdated pipeline v8
All checks were successful
sgeUpdated Smoke Test / smoke-test (push) Successful in 6s
sgeUpdated CI/CD / deploy (push) Successful in 22s
2025-08-29 20:05:03 +03:00
a4791d6a57 Update Front-End after pipeline v4
All checks were successful
sgeUpdated CI/CD / deploy (push) Successful in 20s
sgeUpdated Smoke Test / smoke-test (push) Successful in 6s
2025-08-29 19:40:12 +03:00
168cfaa8a7 Update Back-End after pipeline v6
Some checks failed
sgeUpdated CI/CD / deploy (push) Successful in 22s
sgeUpdated Smoke Test / smoke-test (push) Has been cancelled
2025-08-29 19:39:45 +03:00
710655c1fd Update docker-compose.yml
All checks were successful
sgeUpdated CI/CD / deploy (push) Successful in 22s
sgeUpdated Smoke Test / smoke-test (push) Successful in 6s
2025-08-29 19:37:41 +03:00
6f445f205a Update sgeupdated pipeline v7
All checks were successful
sgeUpdated Smoke Test / smoke-test (push) Successful in 6s
sgeUpdated CI/CD / deploy (push) Successful in 21s
2025-08-29 19:35:49 +03:00
32b9533a33 Update docker-compose.yml
Some checks failed
sgeUpdated CI/CD / deploy (push) Has been cancelled
sgeUpdated Smoke Test / smoke-test (push) Successful in 7s
2025-08-29 19:27:28 +03:00
62829194e2 Update Front-End after pipeline v3
All checks were successful
sgeUpdated CI/CD / deploy (push) Successful in 22s
sgeUpdated Smoke Test / smoke-test (push) Successful in 6s
2025-08-29 19:24:43 +03:00
87a80f63ed Update Back-End after pipeline v5
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 16s
sgeUpdated Smoke Test / smoke-test (push) Has been cancelled
2025-08-29 19:24:21 +03:00
f12c5cb8d4 Update sgeupdated pipeline v6
All checks were successful
sgeUpdated Smoke Test / smoke-test (push) Successful in 6s
sgeUpdated CI/CD / deploy (push) Successful in 29s
Some mistakes in directory
2025-08-29 19:20:39 +03:00
7148bdf834 Update Front-End after pipeline v2
All checks were successful
sgeUpdated CI/CD / deploy (push) Successful in 21s
sgeUpdated Smoke Test / smoke-test (push) Successful in 5s
2025-08-29 19:12:06 +03:00
9eb903a450 Update Back-End after pipeline v4
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 16s
sgeUpdated Smoke Test / smoke-test (push) Successful in 6s
2025-08-29 19:11:38 +03:00
991aef0417 Update sgeupdated pipeline v5
All checks were successful
sgeUpdated Smoke Test / smoke-test (push) Successful in 6s
sgeUpdated CI/CD / deploy (push) Successful in 22s
working on updating the docker
2025-08-29 19:09:11 +03:00
a1c0f71fbf Update Front-End after pipeline
All checks were successful
sgeUpdated CI/CD / deploy (push) Successful in 21s
sgeUpdated Smoke Test / smoke-test (push) Successful in 5s
2025-08-29 00:21:02 +03:00
64c36cb617 Update Back-End after pipeline v3
Some checks failed
sgeUpdated Smoke Test / smoke-test (push) Has been cancelled
sgeUpdated CI/CD / deploy (push) Has been cancelled
2025-08-29 00:20:41 +03:00
0f2bf5a800 Update Front-End after pipeline
All checks were successful
sgeUpdated CI/CD / deploy (push) Successful in 21s
sgeUpdated Smoke Test / smoke-test (push) Successful in 5s
2025-08-29 00:17:33 +03:00
d6375c320a Update Back-End after pipeline v3
All checks were successful
sgeUpdated Smoke Test / smoke-test (push) Successful in 5s
sgeUpdated CI/CD / deploy (push) Successful in 21s
2025-08-29 00:17:07 +03:00
3d440798e3 Update sgeupdated pipeline v4
All checks were successful
sgeUpdated CI/CD / deploy (push) Successful in 22s
sgeUpdated Smoke Test / smoke-test (push) Successful in 6s
Made a force for rebuilding the docker
2025-08-29 00:16:07 +03:00
8cdc00f921 Update sgeupdated pipeline v3
All checks were successful
sgeUpdated Smoke Test / smoke-test (push) Successful in 5s
sgeUpdated CI/CD / deploy (push) Successful in 21s
2025-08-29 00:11:13 +03:00
593e5ceb6a Update Front-End after pipeline
All checks were successful
sgeUpdated CI/CD / deploy (push) Successful in 22s
sgeUpdated Smoke Test / smoke-test (push) Successful in 6s
problem with dockerizing
2025-08-29 00:07:10 +03:00
b2eebfce64 Update Back-End after pipeline v2
All checks were successful
sgeUpdated CI/CD / deploy (push) Successful in 22s
sgeUpdated Smoke Test / smoke-test (push) Successful in 6s
problem with not dockerizing
2025-08-29 00:06:18 +03:00
c3ed359103 Update sgeupdated pipeline v3
All checks were successful
sgeUpdated CI/CD / deploy (push) Successful in 21s
sgeUpdated Smoke Test / smoke-test (push) Successful in 5s
a typo in docker names for front-end and back-end
2025-08-29 00:02:27 +03:00
7b4143ba52 Update sgeupdated pipeline v3
All checks were successful
sgeUpdated Smoke Test / smoke-test (push) Successful in 6s
sgeUpdated CI/CD / deploy (push) Successful in 21s
problem in restarting docker
2025-08-28 23:56:54 +03:00
0322235404 Update Back-End after pipeline
All checks were successful
sgeUpdated CI/CD / deploy (push) Successful in 22s
sgeUpdated Smoke Test / smoke-test (push) Successful in 6s
2025-08-28 23:48:21 +03:00
95a344a7a6 Update Front-End after CI/CD
All checks were successful
sgeUpdated CI/CD / deploy (push) Successful in 21s
sgeUpdated Smoke Test / smoke-test (push) Successful in 5s
2025-08-28 23:45:33 +03:00
c477143b30 Update sgeupdated pipeline v2
Some checks failed
sgeUpdated Smoke Test / smoke-test (push) Successful in 5s
sgeUpdated CI/CD / deploy (push) Failing after 16s
2025-08-28 23:42:13 +03:00
6202f7ec26 Update sgeupdated pipeline
Some checks failed
sgeUpdated Smoke Test / smoke-test (push) Successful in 5s
sgeUpdated CI/CD / deploy (push) Has been cancelled
2025-08-28 23:28:23 +03:00
8eb9835e13 Update sgeupdated pipeline
All checks were successful
sgeUpdated Smoke Test / smoke-test (push) Successful in 6s
sgeUpdated CI/CD / deploy (push) Successful in 22s
2025-08-28 19:09:57 +03:00
08941cc7d5 Update sgeupdated pipeline
Some checks failed
sgeUpdated CI/CD / deploy (push) Failing after 35s
sgeUpdated Smoke Test / smoke-test (push) Has been cancelled
2025-08-28 19:01:37 +03:00
994e81b1fb Add sgeupdated pipeline
Some checks failed
sgeUpdated Smoke Test / smoke-test (push) Has been cancelled
sgeUpdated CI/CD / deploy (push) Has been cancelled
2025-08-28 18:47:24 +03:00
0c03a110e5 DELETE
All checks were successful
sgeUpdated Smoke Test / smoke-test (push) Successful in 6s
2025-08-28 17:56:30 +03:00
7c5eb3a210 Delete .gitea/workflows/deploy.yml
All checks were successful
sgeUpdated Smoke Test / smoke-test (push) Successful in 6s
2025-08-28 17:55:52 +03:00
a943925325 Add a Smoke test workflow
Some checks failed
CI/CD Pipeline / deploy_testing (push) Has been skipped
CI/CD Pipeline / deploy_production (push) Failing after 43s
sgeUpdated Smoke Test / smoke-test (push) Successful in 6s
2025-08-28 17:53:33 +03:00
5bd98fb09d update a Smoke test workflow
Some checks failed
CI/CD Pipeline / deploy_testing (push) Has been skipped
CI/CD Pipeline / deploy_production (push) Failing after 40s
2025-08-27 03:42:02 +03:00
cdb6d98ae7 Add a Smoke test workflow
Some checks failed
CI/CD Pipeline / deploy_testing (push) Has been skipped
CI/CD Pipeline / deploy_production (push) Failing after 15s
2025-08-27 03:40:09 +03:00
243f89457f Add test workflow
Some checks failed
CI/CD Pipeline / deploy_testing (push) Has been skipped
CI/CD Pipeline / deploy_production (push) Failing after 40s
2025-08-27 03:34:14 +03:00
03875dde53 Add test workflow updated name
Some checks failed
CI/CD Pipeline / deploy_testing (push) Has been skipped
CI/CD Pipeline / deploy_production (push) Failing after 16s
2025-08-27 03:32:21 +03:00
e695d06f5b Add CI/CD deploy workflows
Some checks failed
CI/CD Pipeline / deploy_testing (push) Has been skipped
CI/CD Pipeline / deploy_production (push) Failing after 56s
2025-08-27 03:04:15 +03:00
837353bc45 Add test workflow
Some checks failed
CI/CD Pipeline / deploy_production (push) Failing after 16s
CI/CD Pipeline / deploy_testing (push) Has been skipped
2025-08-27 03:02:45 +03:00
2459ba092b Add CI/CD deploy workflow update
Some checks failed
CI/CD Pipeline / deploy_testing (push) Has been skipped
CI/CD Pipeline / deploy_production (push) Failing after 1m48s
2025-08-27 03:00:10 +03:00
4bfd2ee1f8 Add CI/CD deploy workflow 2025-08-27 02:45:09 +03:00
95fbbc340e Add .gitea/workflows/deploy.yml 2025-08-27 02:43:00 +03:00
78ffa4fe7e Merge pull request 'multi-emission-feature' (#14) from multi-emission-feature into main
Reviewed-on: BLC/sgeUpdated#14
2025-08-19 09:26:46 +03:00
a14bc4e73a Add cityID in creation and update and edit some graphics in the map 2025-08-19 09:24:29 +03:00
50c6a2ef5b cloudsystem column added 2025-08-19 07:36:45 +03:00
d4e40f5a6b just pushing this to resolve merge conflict i have no changes made in this commit 2025-08-19 07:33:53 +03:00
bbb0976aa1 added the cloudsystem column 2025-08-19 07:16:17 +03:00
085a417016 Fix dropdown selection overflow while scrolling 2025-08-19 06:51:50 +03:00
edd8feb4d2 Add optimization to show data faster using Memo 2025-08-19 06:43:22 +03:00
2d39883b7f filtering raw data page 2025-08-19 06:17:37 +03:00
21b757cf77 Fix small translation in Map 2025-08-19 05:39:16 +03:00
8bd6d94174 Fix the DataCenterOverview tab display by removing project relation 2025-08-19 05:39:02 +03:00
Ali Sadeghi
b5901a049c Merge: Add city to datacenter, cloudsystem to summary, fix listener 2025-08-19 04:43:53 +03:00
82f86a62ca Fix issue in updating datacenter
Found a hibernate cascade issue and was fixed by reuse the existing collection instaed of creating a new one in updating the datacenter entity
2025-08-19 00:15:51 +03:00
47959fb35f Make the datacenter creation modal mobile friendly 2025-08-19 00:08:42 +03:00
2257ec79f6 Make creation of default area nested in city initialization 2025-08-19 00:08:01 +03:00
17d77fcda7 Fix message queue data misnaming 2025-08-19 00:07:20 +03:00
3245040274 Merge pull request 'Multi Emission Sources Feature' (#10) from multi-emission-feature into main
Reviewed-on: BLC/sgeUpdated#10
2025-08-18 08:09:49 +03:00
92d88df213 Fix Backend error:
Error loading data: Exception while fetching data (/vmEmissionSummary) : org.hibernate.exception.SQLGrammarException: could not extract ResultSet
2025-08-18 08:03:40 +03:00
a66b01334d Small bug fix 2025-08-18 08:02:34 +03:00
c7e60c25eb Add datacenter with multiple emission source and inputs 2025-08-18 06:12:19 +03:00
ebd997a33d Fix the datacenter query according to the changes in backend 2025-08-18 05:38:51 +03:00
dd04a057b1 Comment not needed orgnization code 2025-08-18 05:38:39 +03:00
d224905ba0 Make the Datacenter module structure following the whole code structure 2025-08-18 05:38:20 +03:00
b5ceb1591e Merge Backend Updates 2025-08-18 04:28:45 +03:00
89b4644983 few translation edits and changing it to use vmEmission query 2025-08-09 20:08:56 +03:00
39fffadbd2 fixed issue GUI and Datacenter tab related 2025-08-07 19:28:56 +03:00
49 changed files with 6022 additions and 4340 deletions

View File

@@ -0,0 +1,29 @@
name: sgeUpdated CI/CD
on:
pull_request:
types:
- closed # Fires when a PR is closed (either merged or manually closed)
branches:
- main # Only when PR targets main
jobs:
deploy:
if: github.event.pull_request.merged == true # Run only if the PR was merged (not just closed)
runs-on: ubuntu-latest
steps:
- name: Setup SSH
run: |
mkdir -p ~/.ssh/
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan ${{ secrets.SERVER_HOST }} >> ~/.ssh/known_hosts
- name: Run deploy script on server
run: |
ssh ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_HOST }} << 'EOF'
echo "✅ PR merged into main — running deploy script..."
cd /home/ubuntu/Bgreen/sgeUpdated
./deploy.sh
EOF

24
config.conf Normal file
View File

@@ -0,0 +1,24 @@
# SGE Application Configuration
# This file contains configuration for both backend and frontend
# Database Configuration
SPRING_DATASOURCE_URL=jdbc:postgresql://bgreen-database:5432/sge
SPRING_DATASOURCE_USERNAME=sge
SPRING_DATASOURCE_PASSWORD=147
# Server Configuration
SERVER_PORT=8080
# Mail Configuration
MAIL_HOSTNAME=mail.spacemail.com
MAIL_SMTP_PORT=465
MAIL_ADDRESS=info@blc-css.com
MAIL_PASSWORD=123456Bb@
# React Application Configuration
# API Configuration
API_PROTOCOL=http
API_HOST=bgreen-backend
# Application URLs
APP_SURVEY_BASE_URL=https://bgreen.blc-css.com

74
deploy.sh Executable file
View File

@@ -0,0 +1,74 @@
#!/bin/bash
set -euo pipefail
cd /home/ubuntu/Bgreen/sgeUpdated
echo "📦 Fetching latest changes from origin/main..."
git fetch myfork main
# Detect which files changed between local HEAD and the latest remote version
CHANGED_FILES=$(git diff --name-only HEAD myfork/main || true)
if [ -z "$CHANGED_FILES" ]; then
echo "✅ No file changes detected between HEAD and origin/main."
else
echo "🪶 Changed files:"
echo "$CHANGED_FILES"
fi
# Update to the latest version
git reset --hard myfork/main
BACKEND_CHANGED=false
FRONTEND_CHANGED=false
# Check if backend folder changed
if echo "$CHANGED_FILES" | grep "^sge-backend/" | grep -qv "README.md$"; then
BACKEND_CHANGED=true
fi
# Check if frontend folder changed
if echo "$CHANGED_FILES" | grep "^sge-frontend/" | grep -qv "README.md$"; then
FRONTEND_CHANGED=true
fi
# -----------------------
# Backend section
# -----------------------
if [ "$BACKEND_CHANGED" = true ]; then
echo "⚡ Backend changes detected."
cd sge-backend
echo "Running Maven build..."
/opt/apache-maven-3.9.11/bin/mvn clean install -DskipTests
cd ../..
echo "Rebuilding backend Docker container..."
docker compose up -d --build bgreen-backend
else
echo "✅ No backend changes."
fi
# -----------------------
# Frontend section
# -----------------------
if [ "$FRONTEND_CHANGED" = true ]; then
echo "⚡ Frontend changes detected."
cd sge-frontend
# Check if package.json or package-lock.json changed
if echo "$CHANGED_FILES" | grep -qE "^sge-frontend/(package\.json|package-lock\.json)$"; then
echo "📦 package.json changed. Running 'npm instal' and 'npm run build'..."
npm install
npm run build
else
echo "📦 only code changes. Running 'npm run build'..."
npm run build
fi
cd ../..
echo "Rebuilding frontend Docker container..."
docker compose up -d --build bgreen-frontend
else
echo "✅ No frontend changes."
fi
echo "✅ Deployment complete."

69
deploy.sh.save Executable file
View File

@@ -0,0 +1,69 @@
#!/bin/bash
set -euo pipefail
export GIT_SSH_COMMAND="ssh -i ~/.ssh/deploy_id_rsa -o StrictHostKeyC
cd /home/ubuntu/Bgreen/sgeUpdated
echo "📦 Fetching latest changes from origin/main..."
git fetch origin main
# Detect which files changed between local HEAD and the latest remote version
CHANGED_FILES=$(git diff --name-only HEAD origin/main || true)
if [ -z "$CHANGED_FILES" ]; then
echo "✅ No file changes detected between HEAD and origin/main."
else
echo "🪶 Changed files:"
echo "$CHANGED_FILES"
fi
# Update to the latest version
git reset --hard origin/main
BACKEND_CHANGED=false
FRONTEND_CHANGED=false
# Check if backend folder changed
if echo "$CHANGED_FILES" | grep -q "^sge-backend/"; then
BACKEND_CHANGED=true
fi
# Check if frontend folder changed
if echo "$CHANGED_FILES" | grep -q "^sge-frontend/"; then
FRONTEND_CHANGED=true
fi
# -----------------------
# Backend section
# -----------------------
if [ "$BACKEND_CHANGED" = true ]; then
echo "⚡ Backend changes detected."
cd sge-backend
echo "Running Maven build..."
/opt/apache-maven-3.9.11/bin/mvn clean install -DskipTests
cd ..
echo "Rebuilding backend Docker container..."
docker compose up -d --build bgreen-backend
else
echo "✅ No backend changes."
fi
# -----------------------
# Frontend section
# -----------------------
if [ "$FRONTEND_CHANGED" = true ]; then
echo "⚡ Frontend changes detected."
cd sge-frontend
echo "Running npm build..."
npm install
npm run build
cd ..
echo "Rebuilding frontend Docker container..."
docker compose up -d --build bgreen-frontend
else
echo "✅ No frontend changes."
fi
echo "✅ Deployment complete."

39
docker-compose.yml Normal file
View File

@@ -0,0 +1,39 @@
services:
bgreen-backend:
build:
context: ./sge-backend
dockerfile: Dockerfile
ports:
- "8080:8080"
env_file:
- ./config.conf
environment:
SPRING_PROFILES_ACTIVE: docker
depends_on:
- database
restart: unless-stopped
bgreen-frontend:
build:
context: ./sge-frontend
dockerfile: Dockerfile
ports:
- "80:80"
env_file:
- ./config.conf
restart: unless-stopped
database:
image: postgres:15
environment:
POSTGRES_DB: sge
POSTGRES_USER: sge
POSTGRES_PASSWORD: 147
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
restart: unless-stopped
volumes:
postgres_data:

1
sge-backend/README.md Normal file
View File

@@ -0,0 +1 @@
## CI/CD Pipeline Check v23

View File

@@ -6,12 +6,12 @@
<parent> <parent>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId> <artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.4</version> <version>2.5.5</version>
<relativePath /> <relativePath />
</parent> </parent>
<groupId>com.sgs</groupId> <groupId>com.sgs</groupId>
<artifactId>sgs</artifactId> <artifactId>sgs</artifactId>
<version>0.0.1-SNAPSHOT</version> <version>0.0.2-SNAPSHOT</version>
<name>sgs</name> <name>sgs</name>
<description>SGS project for Spring Boot</description> <description>SGS project for Spring Boot</description>
<properties> <properties>

View File

@@ -121,7 +121,8 @@ public class SgsApplication implements CommandLineRunner {
@Autowired @Autowired
public SgsApplication(RoleService roleService, PermissionService permissionService, RoleRepo roleRepo, public SgsApplication(RoleService roleService, PermissionService permissionService, RoleRepo roleRepo,
AreaService areaService, NeighborhoodRepo neighborhoodRepo, NeighborhoodService neighborhoodService, CityService cityService, AreaService areaService, NeighborhoodRepo neighborhoodRepo, NeighborhoodService neighborhoodService,
CityService cityService,
CityRepo cityRepo, DistrictRepo districtRepo, DistrictService districtService, CountryRepo countryRepo, CityRepo cityRepo, DistrictRepo districtRepo, DistrictService districtService, CountryRepo countryRepo,
CountryService countryService, OrganizationService organizationService, UserService userService, CountryService countryService, OrganizationService organizationService, UserService userService,
PasswordEncoder passwordEncoder, SectorService sectorService, SubSectorService subSectorService, PasswordEncoder passwordEncoder, SectorService sectorService, SubSectorService subSectorService,
@@ -186,7 +187,7 @@ public class SgsApplication implements CommandLineRunner {
admin.setFirstName("Seda"); admin.setFirstName("Seda");
admin.setLastName("Kemikli"); admin.setLastName("Kemikli");
admin.setEmail("seda.kemikli@blc-css.com"); admin.setEmail("seda.kemikli@blc-css.com");
admin.setPhoneNumber("11111111"); admin.setPhoneNumber("11111511");
admin.setPassword(passwordEncoder.encode("admin")); admin.setPassword(passwordEncoder.encode("admin"));
// if (organizations.size() == 1) { // if (organizations.size() == 1) {
// admin.setOrganizations(organizations); // admin.setOrganizations(organizations);
@@ -858,6 +859,7 @@ public class SgsApplication implements CommandLineRunner {
} }
if (cityService.findAll().isEmpty()) { if (cityService.findAll().isEmpty()) {
createCitiesFromJson(); createCitiesFromJson();
createDefaultArea();
} }
if (districtService.findAll().isEmpty()) { if (districtService.findAll().isEmpty()) {
createDistrictFromJson(); createDistrictFromJson();
@@ -865,16 +867,13 @@ public class SgsApplication implements CommandLineRunner {
if (neighborhoodService.findAll().isEmpty()) { if (neighborhoodService.findAll().isEmpty()) {
createNeighborhoodsFromJson(); createNeighborhoodsFromJson();
} }
if (!cityService.findAll().isEmpty()) {
createDefaultArea();
}
} }
void createDefaultArea() { void createDefaultArea() {
// Check if default area already exists // Check if default area already exists
List<Area> existingAreas = areaService.findAll(); List<Area> existingAreas = areaService.findAll();
boolean defaultAreaExists = existingAreas.stream() boolean defaultAreaExists = existingAreas.stream()
.anyMatch(area -> "Turkiye".equals(area.getTag()) && area.isDefaultArea()); .anyMatch(area -> "Turkiye".equals(area.getTag()) && area.isDefaultArea());
if (!defaultAreaExists) { if (!defaultAreaExists) {
Area defaultArea = new Area(); Area defaultArea = new Area();

View File

@@ -1,4 +1,5 @@
package com.sgs.graphql.dataCenter.domain; package com.sgs.graphql.dataCenter.domain;
import com.fasterxml.jackson.annotation.JsonBackReference; import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonManagedReference; import com.fasterxml.jackson.annotation.JsonManagedReference;
import com.sgs.graphql.area.domain.Area; import com.sgs.graphql.area.domain.Area;
@@ -15,7 +16,6 @@ import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption; import org.hibernate.annotations.LazyCollectionOption;
import org.hibernate.annotations.Fetch; import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode; import org.hibernate.annotations.FetchMode;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -46,9 +46,7 @@ public class DataCenter extends BaseDomain {
private Double latitude; private Double latitude;
private Double longitude; private Double longitude;
@Column(name = "data_center_name") @Column(name = "data_center_name")
@Transactional
public String getDataCenter() { public String getDataCenter() {
return dataCenter; return dataCenter;
} }
@@ -96,7 +94,6 @@ public class DataCenter extends BaseDomain {
this.number = number; this.number = number;
} }
@ManyToOne(fetch = FetchType.EAGER) @ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "sector_id") @JoinColumn(name = "sector_id")
public Sector getSector() { public Sector getSector() {

View File

@@ -1,18 +1,26 @@
package com.sgs.graphql.dataCenter.mutation; package com.sgs.graphql.dataCenter.mutation;
import com.sgs.exception.GraphQLCustomException;
import com.sgs.graphql.dataCenter.mutation.mapper.DataCenterMapper; import com.sgs.graphql.dataCenter.mutation.mapper.DataCenterMapper;
import com.sgs.graphql.dataCenter.service.DataCenterService; import com.sgs.graphql.dataCenter.service.DataCenterService;
import com.sgs.graphql.dataCenter.domain.DataCenter; import com.sgs.graphql.dataCenter.domain.DataCenter;
import com.sgs.graphql.dataCenter.mutation.input.DataCenterCreateInput; import com.sgs.graphql.dataCenter.mutation.input.DataCenterCreateInput;
import com.sgs.graphql.dataCenter.mutation.input.DataCenterUpdateInput; import com.sgs.graphql.dataCenter.mutation.input.DataCenterUpdateInput;
import com.sgs.graphql.permission.domain.PermissionName; import com.sgs.graphql.permission.domain.PermissionName;
import com.sgs.graphql.systemHistory.enums.LogType;
import com.sgs.graphql.systemHistory.mutation.SystemLogger;
import com.sgs.graphql.userHistory.mutation.UserLogger;
import com.sgs.graphql.userNotification.mutation.UserNotificationMutation;
import graphql.kickstart.tools.GraphQLMutationResolver; import graphql.kickstart.tools.GraphQLMutationResolver;
import graphql.schema.DataFetchingEnvironment;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import javax.transaction.Transactional;
import javax.validation.Valid; import javax.validation.Valid;
import java.util.NoSuchElementException;
import java.util.UUID; import java.util.UUID;
@Validated @Validated
@@ -21,57 +29,128 @@ public class DataCenterMutation implements GraphQLMutationResolver {
private final DataCenterService dataCenterService; private final DataCenterService dataCenterService;
private final DataCenterMapper dataCenterMapper; private final DataCenterMapper dataCenterMapper;
private final SystemLogger systemLogger;
private final UserLogger userLogger;
private final UserNotificationMutation notificationMutation;
@Autowired @Autowired
public DataCenterMutation(DataCenterService dataCenterService, DataCenterMapper dataCenterMapper) { public DataCenterMutation(DataCenterService dataCenterService, DataCenterMapper dataCenterMapper,
SystemLogger systemLogger, UserLogger userLogger,
UserNotificationMutation notificationMutation) {
this.dataCenterService = dataCenterService; this.dataCenterService = dataCenterService;
this.dataCenterMapper = dataCenterMapper; this.dataCenterMapper = dataCenterMapper;
this.systemLogger = systemLogger;
this.userLogger = userLogger;
this.notificationMutation = notificationMutation;
} }
@PreAuthorize("hasAuthority('" + PermissionName.DATA_CENTER_CREATE + "')") @PreAuthorize("hasAuthority('" + PermissionName.DATA_CENTER_CREATE + "')")
public DataCenter createDataCenter(@Valid DataCenterCreateInput input) { @Transactional
// Check for duplicate externalId public DataCenter createDataCenter(@Valid DataCenterCreateInput input, DataFetchingEnvironment environment) {
if (input.getExternalId() != null && dataCenterService.existsByExternalId(input.getExternalId())) { try {
throw new RuntimeException("This external id already exists: " + input.getExternalId()); // Check for duplicate externalId
if (input.getExternalId() != null && dataCenterService.existsByExternalId(input.getExternalId())) {
throw new GraphQLCustomException("2010", input.getExternalId().toString());
}
DataCenter dataCenter = dataCenterMapper.toEntity(input);
// Set auto-generated number if not provided
if (dataCenter.getNumber() == null) {
Integer maxNumber = dataCenterService.findMaxNumber();
dataCenter.setNumber((maxNumber == null) ? 1 : maxNumber + 1);
}
DataCenter savedDataCenter = dataCenterService.save(dataCenter);
// Log and notify
String dataCenterName = savedDataCenter.getDataCenter() != null ? savedDataCenter.getDataCenter()
: "DataCenter #" + savedDataCenter.getNumber();
systemLogger.createSystemLog(LogType.INFO, dataCenterName + " adlı veri merkezi oluşturuldu");
userLogger.createUserLog(LogType.INFO, dataCenterName + " adlı veri merkezi oluşturuldu", environment);
notificationMutation.createNotification(environment, "Veri Merkezi",
dataCenterName + " adlı veri merkezi oluşturuldu", "Yeni kayıt");
return savedDataCenter;
} catch (GraphQLCustomException e) {
throw e;
} catch (Exception e) {
systemLogger.createSystemLog(LogType.ERROR,
"Yeni veri merkezi oluşturulurken hata oluştu: " + e.getMessage());
throw e;
} }
DataCenter dataCenter = dataCenterMapper.toEntity(input);
// Set auto-generated number if not provided
if (dataCenter.getNumber() == null) {
Integer maxNumber = dataCenterService.getRepository().findMaxNumber();
dataCenter.setNumber((maxNumber == null) ? 1 : maxNumber + 1);
}
return dataCenterService.save(dataCenter);
} }
@PreAuthorize("hasAuthority('" + PermissionName.DATA_CENTER_UPDATE + "')") @PreAuthorize("hasAuthority('" + PermissionName.DATA_CENTER_UPDATE + "')")
public DataCenter updateDataCenter(UUID id, @Valid DataCenterUpdateInput input) { @Transactional
return dataCenterService.findById(id) public DataCenter updateDataCenter(UUID id, @Valid DataCenterUpdateInput input,
.map(dataCenter -> { DataFetchingEnvironment environment) {
// Check for duplicate externalId if it's being updated try {
if (input.getExternalId() != null && DataCenter dataCenter = dataCenterService.findById(id)
!input.getExternalId().equals(dataCenter.getExternalId()) && .orElseThrow(() -> new NoSuchElementException("Data center not found with ID: " + id));
dataCenterService.existsByExternalId(input.getExternalId())) {
throw new RuntimeException("This external id already exists: " + input.getExternalId()); // Check for duplicate externalId if it's being updated
} if (input.getExternalId() != null &&
return dataCenterService.update(dataCenterMapper.updateEntity(dataCenter, input)); !input.getExternalId().equals(dataCenter.getExternalId()) &&
}) dataCenterService.existsByExternalId(input.getExternalId())) {
.orElseThrow(() -> new RuntimeException("Data center not found with ID: " + id)); throw new GraphQLCustomException("2010", input.getExternalId().toString());
}
DataCenter updatedDataCenter = dataCenterService.update(dataCenterMapper.updateEntity(dataCenter, input));
// Log and notify
String dataCenterName = updatedDataCenter.getDataCenter() != null ? updatedDataCenter.getDataCenter()
: "DataCenter #" + updatedDataCenter.getNumber();
systemLogger.createSystemLog(LogType.INFO, dataCenterName + " adlı veri merkezi güncellendi");
userLogger.createUserLog(LogType.INFO, dataCenterName + " adlı veri merkezi güncellendi", environment);
notificationMutation.createNotification(environment, "Veri Merkezi",
dataCenterName + " adlı veri merkezi güncellendi", "Güncelleme");
return updatedDataCenter;
} catch (GraphQLCustomException e) {
throw e;
} catch (NoSuchElementException e) {
systemLogger.createSystemLog(LogType.ERROR, "Veri merkezi bulunamadı: " + id);
throw e;
} catch (Exception e) {
systemLogger.createSystemLog(LogType.ERROR, "Veri merkezi güncellenirken hata oluştu: " + e.getMessage());
throw e;
}
} }
@PreAuthorize("hasAuthority('" + PermissionName.DATA_CENTER_DELETE + "')") @PreAuthorize("hasAuthority('" + PermissionName.DATA_CENTER_DELETE + "')")
public Boolean deleteDataCenter(UUID id) { @Transactional
public String deleteDataCenter(UUID id, DataFetchingEnvironment environment) {
String dataCenterName = "";
try { try {
DataCenter dataCenter = dataCenterService.findById(id) DataCenter dataCenter = dataCenterService.findById(id)
.orElseThrow(() -> new RuntimeException("Data center not found with ID: " + id)); .orElseThrow(() -> new NoSuchElementException("Data center not found with ID: " + id));
dataCenterName = dataCenter.getDataCenter() != null ? dataCenter.getDataCenter()
: "DataCenter #" + dataCenter.getNumber();
// Check if data center has physical machines or other dependencies
if (dataCenter.getPhysicalMachines() != null && !dataCenter.getPhysicalMachines().isEmpty()) {
String message = "Silinmeye çalışılan veri merkezinin fiziksel makineleri olduğu için silinememektedir";
systemLogger.createSystemLog(LogType.WARN, dataCenterName + ": " + message);
return message;
}
dataCenterService.delete(dataCenter); dataCenterService.delete(dataCenter);
return true;
// Log and notify
systemLogger.createSystemLog(LogType.INFO, dataCenterName + " adlı veri merkezi silindi");
userLogger.createUserLog(LogType.INFO, dataCenterName + " adlı veri merkezi silindi", environment);
notificationMutation.createNotification(environment, "Veri Merkezi",
dataCenterName + " adlı veri merkezi silindi", "Silme");
return "true";
} catch (NoSuchElementException e) {
systemLogger.createSystemLog(LogType.ERROR, "Veri merkezi bulunamadı: " + id);
return "false";
} catch (Exception e) { } catch (Exception e) {
System.out.println("DataCenter deletion error: " + e.getMessage()); systemLogger.createSystemLog(LogType.ERROR, "Veri merkezi silinirken hata oluştu: " + e.getMessage());
return false; return "false";
} }
} }
} }

View File

@@ -16,7 +16,6 @@ public class DataCenterCreateInput extends BaseCreateInput {
private Integer number; private Integer number;
private Double consuptionAmount; private Double consuptionAmount;
@NotNull(message = "Alan ID gereklidir")
private UUID areaId; private UUID areaId;
private UUID cityId; private UUID cityId;

View File

@@ -4,6 +4,8 @@ import com.sgs.lib.dao.mutation.input.BaseUpdateInput;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import javax.validation.constraints.NotNull;
public class DataCenterUpdateInput extends BaseUpdateInput { public class DataCenterUpdateInput extends BaseUpdateInput {
private String dataCenter; private String dataCenter;
private Integer externalId; private Integer externalId;
@@ -12,6 +14,7 @@ public class DataCenterUpdateInput extends BaseUpdateInput {
private UUID areaId; private UUID areaId;
private UUID cityId; private UUID cityId;
@NotNull(message = "Sektör ID gereklidir")
private UUID sectorId; private UUID sectorId;
private UUID subSectorId; private UUID subSectorId;
private UUID emissionScopeId; private UUID emissionScopeId;

View File

@@ -97,16 +97,19 @@ public class DataCenterMapper extends BaseCreateUpdateMapper<DataCenter, DataCen
// Set EmissionSource // Set EmissionSource
if (emissionSourceInput.getEmissionSourceId() != null) { if (emissionSourceInput.getEmissionSourceId() != null) {
dcEmissionSource.setEmissionSource(emissionSourceService.findById(UUID.fromString(emissionSourceInput.getEmissionSourceId())).orElse(null)); dcEmissionSource.setEmissionSource(emissionSourceService
.findById(UUID.fromString(emissionSourceInput.getEmissionSourceId())).orElse(null));
} }
// Set ConsuptionUnit // Set ConsuptionUnit
if (emissionSourceInput.getConsuptionUnitId() != null) { if (emissionSourceInput.getConsuptionUnitId() != null) {
dcEmissionSource.setConsuptionUnit(consuptionUnitService.findById(UUID.fromString(emissionSourceInput.getConsuptionUnitId())).orElse(null)); dcEmissionSource.setConsuptionUnit(consuptionUnitService
.findById(UUID.fromString(emissionSourceInput.getConsuptionUnitId())).orElse(null));
} }
// Set optional fields // Set optional fields
dcEmissionSource.setIsDefault(emissionSourceInput.getIsDefault() != null ? emissionSourceInput.getIsDefault() : false); dcEmissionSource.setIsDefault(
emissionSourceInput.getIsDefault() != null ? emissionSourceInput.getIsDefault() : false);
dcEmissionSource.setPercentage(emissionSourceInput.getPercentage()); dcEmissionSource.setPercentage(emissionSourceInput.getPercentage());
dataCenterEmissionSources.add(dcEmissionSource); dataCenterEmissionSources.add(dcEmissionSource);
@@ -163,28 +166,31 @@ public class DataCenterMapper extends BaseCreateUpdateMapper<DataCenter, DataCen
// Handle multiple emission sources update if provided // Handle multiple emission sources update if provided
if (input.getDataCenterEmissionSources() != null) { if (input.getDataCenterEmissionSources() != null) {
// Clear existing emission sources and add new ones // Clear existing emission sources from the managed collection
entity.getDataCenterEmissionSources().clear(); entity.getDataCenterEmissionSources().clear();
List<DataCenterEmissionSource> dataCenterEmissionSources = new ArrayList<>(); // Add new emission sources to the same managed collection
for (DataCenterEmissionSourceInput emissionSourceInput : input.getDataCenterEmissionSources()) { for (DataCenterEmissionSourceInput emissionSourceInput : input.getDataCenterEmissionSources()) {
DataCenterEmissionSource dcEmissionSource = new DataCenterEmissionSource(); DataCenterEmissionSource dcEmissionSource = new DataCenterEmissionSource();
dcEmissionSource.setDataCenter(entity); dcEmissionSource.setDataCenter(entity);
if (emissionSourceInput.getEmissionSourceId() != null) { if (emissionSourceInput.getEmissionSourceId() != null) {
dcEmissionSource.setEmissionSource(emissionSourceService.findById(UUID.fromString(emissionSourceInput.getEmissionSourceId())).orElse(null)); dcEmissionSource.setEmissionSource(emissionSourceService
.findById(UUID.fromString(emissionSourceInput.getEmissionSourceId())).orElse(null));
} }
if (emissionSourceInput.getConsuptionUnitId() != null) { if (emissionSourceInput.getConsuptionUnitId() != null) {
dcEmissionSource.setConsuptionUnit(consuptionUnitService.findById(UUID.fromString(emissionSourceInput.getConsuptionUnitId())).orElse(null)); dcEmissionSource.setConsuptionUnit(consuptionUnitService
.findById(UUID.fromString(emissionSourceInput.getConsuptionUnitId())).orElse(null));
} }
dcEmissionSource.setIsDefault(emissionSourceInput.getIsDefault() != null ? emissionSourceInput.getIsDefault() : false); dcEmissionSource.setIsDefault(
emissionSourceInput.getIsDefault() != null ? emissionSourceInput.getIsDefault() : false);
dcEmissionSource.setPercentage(emissionSourceInput.getPercentage()); dcEmissionSource.setPercentage(emissionSourceInput.getPercentage());
dataCenterEmissionSources.add(dcEmissionSource); // Add to the existing managed collection instead of creating a new one
entity.getDataCenterEmissionSources().add(dcEmissionSource);
} }
entity.setDataCenterEmissionSources(dataCenterEmissionSources);
} }
// New attributes (partial update - only if provided) // New attributes (partial update - only if provided)

View File

@@ -11,17 +11,16 @@ import javax.transaction.Transactional;
import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import com.sgs.graphql.auth.service.AuthorizationService;
import com.sgs.graphql.dataCenter.domain.DataCenter; import com.sgs.graphql.dataCenter.domain.DataCenter;
import com.sgs.graphql.dataCenter.domain.PhysicalMachine; import com.sgs.graphql.dataCenter.domain.PhysicalMachine;
import com.sgs.graphql.dataCenter.query.pagination.DataCenterPageable; import com.sgs.graphql.dataCenter.query.pagination.DataCenterPageable;
import com.sgs.graphql.dataCenter.repo.DataCenterRepo;
import com.sgs.graphql.dataCenter.repo.PhysicalMachineRepo;
import com.sgs.graphql.dataCenter.repo.criteria.DataCenterCriteria; import com.sgs.graphql.dataCenter.repo.criteria.DataCenterCriteria;
import com.sgs.graphql.dataCenter.service.DataCenterService; import com.sgs.graphql.dataCenter.service.DataCenterService;
import com.sgs.graphql.systemHistory.mutation.SystemLogger; import com.sgs.graphql.dataCenter.service.PhysicalMachineService;
import com.sgs.graphql.permission.domain.PermissionName;
import com.sgs.lib.dao.query.pagination.Pagination; import com.sgs.lib.dao.query.pagination.Pagination;
import com.sgs.lib.dao.query.sort.SortBy; import com.sgs.lib.dao.query.sort.SortBy;
@@ -30,48 +29,46 @@ import graphql.kickstart.tools.GraphQLQueryResolver;
@Component @Component
public class DataCenterQueryResolver implements GraphQLQueryResolver { public class DataCenterQueryResolver implements GraphQLQueryResolver {
private final DataCenterService DataCenterService; private final DataCenterService dataCenterService;
private final DataCenterRepo dataCenterRepo; private final PhysicalMachineService physicalMachineService;
private final PhysicalMachineRepo physicalMachineRepo;
private final AuthorizationService authorizationService;
private final SystemLogger systemLogger;
@Autowired @Autowired
public DataCenterQueryResolver(AuthorizationService authorizationService, SystemLogger systemLogger, DataCenterService DataCenterService, DataCenterRepo dataCenterRepo, PhysicalMachineRepo physicalMachineRepo) { public DataCenterQueryResolver(DataCenterService dataCenterService, PhysicalMachineService physicalMachineService) {
this.DataCenterService = DataCenterService; this.dataCenterService = dataCenterService;
this.dataCenterRepo = dataCenterRepo; this.physicalMachineService = physicalMachineService;
this.physicalMachineRepo = physicalMachineRepo;
this.authorizationService = authorizationService;
this.systemLogger = systemLogger;
} }
@PreAuthorize("hasAuthority('" + PermissionName.DATA_CENTER_READ + "')")
public DataCenter dataCenter(UUID id) { public DataCenter dataCenter(UUID id) {
return DataCenterService.findById(id).orElse(null); return dataCenterService.findById(id).orElse(null);
} }
@Transactional @Transactional
@PreAuthorize("hasAuthority('" + PermissionName.DATA_CENTER_READ + "')")
public List<DataCenter> dataCenters(DataCenterCriteria criteria, List<SortBy> sortBy) { public List<DataCenter> dataCenters(DataCenterCriteria criteria, List<SortBy> sortBy) {
List<DataCenter> dataCenters = DataCenterService.filterWithSort(ObjectUtils.defaultIfNull(criteria, new DataCenterCriteria()), return dataCenterService.filterWithSort(ObjectUtils.defaultIfNull(criteria, new DataCenterCriteria()),
Sort.by(ObjectUtils.defaultIfNull(sortBy, new ArrayList<SortBy>()) Sort.by(ObjectUtils.defaultIfNull(sortBy, new ArrayList<SortBy>())
.stream() .stream()
.map(SortBy::toOrder) .map(SortBy::toOrder)
.collect(Collectors.toList()))); .collect(Collectors.toList())));
return dataCenters;
} }
public DataCenterPageable paginateDataCenters(Pagination pagination, DataCenterCriteria criteria, List<SortBy> sortBy) { @PreAuthorize("hasAuthority('" + PermissionName.PAGINATE_DATACENTERS_GET + "')")
return new DataCenterPageable(DataCenterService.filterWithPaginate(ObjectUtils.defaultIfNull(criteria, new DataCenterCriteria()), public DataCenterPageable paginateDataCenters(Pagination pagination, DataCenterCriteria criteria,
Pagination.toPageRequest(pagination, sortBy))); List<SortBy> sortBy) {
return new DataCenterPageable(
dataCenterService.filterWithPaginate(ObjectUtils.defaultIfNull(criteria, new DataCenterCriteria()),
Pagination.toPageRequest(pagination, sortBy)));
} }
@PreAuthorize("hasAuthority('" + PermissionName.DATA_CENTER_READ + "')")
public Optional<DataCenter> getByNumber(Integer id) { public Optional<DataCenter> getByNumber(Integer number) {
return dataCenterRepo.findByNumber(id).stream().findFirst(); return dataCenterService.findByNumber(number);
} }
@PreAuthorize("hasAuthority('" + PermissionName.DATA_CENTER_READ + "')")
public List<PhysicalMachine> physicalMachines(UUID datacenterId) { public List<PhysicalMachine> physicalMachines(UUID datacenterId) {
return physicalMachineRepo.findByDatacenterId(datacenterId); return physicalMachineService.findByDatacenterId(datacenterId);
} }
} }

View File

@@ -2,7 +2,8 @@ package com.sgs.graphql.dataCenter.repo;
import com.sgs.graphql.dataCenter.domain.DataCenter; import com.sgs.graphql.dataCenter.domain.DataCenter;
import com.sgs.graphql.dataCenter.domain.DataCenterEmissionSource; import com.sgs.graphql.dataCenter.domain.DataCenterEmissionSource;
import org.springframework.data.jpa.repository.JpaRepository; import com.sgs.lib.dao.repo.BaseRepo;
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param; import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
@@ -11,7 +12,7 @@ import java.util.List;
import java.util.Optional; import java.util.Optional;
@Repository @Repository
public interface DataCenterEmissionSourceRepo extends JpaRepository<DataCenterEmissionSource, String> { public interface DataCenterEmissionSourceRepo extends BaseRepo<DataCenterEmissionSource> {
List<DataCenterEmissionSource> findByDataCenter(DataCenter dataCenter); List<DataCenterEmissionSource> findByDataCenter(DataCenter dataCenter);

View File

@@ -0,0 +1,6 @@
package com.sgs.graphql.dataCenter.repo.criteria;
import com.sgs.lib.dao.repo.criteria.BaseCriteria;
public class DataCenterEmissionSourceCriteria extends BaseCriteria {
}

View File

@@ -0,0 +1,6 @@
package com.sgs.graphql.dataCenter.repo.criteria;
import com.sgs.lib.dao.repo.criteria.BaseCriteria;
public class PhysicalMachineCriteria extends BaseCriteria {
}

View File

@@ -0,0 +1,6 @@
package com.sgs.graphql.dataCenter.repo.criteria;
import com.sgs.lib.dao.repo.criteria.BaseCriteria;
public class VMCriteria extends BaseCriteria {
}

View File

@@ -0,0 +1,17 @@
package com.sgs.graphql.dataCenter.repo.criteria.spec;
import com.sgs.graphql.dataCenter.domain.DataCenterEmissionSource;
import com.sgs.graphql.dataCenter.repo.criteria.DataCenterEmissionSourceCriteria;
import com.sgs.lib.dao.repo.criteria.spec.BaseCriteriaSpec;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Component;
@Component
public class DataCenterEmissionSourceCriteriaSpec
extends BaseCriteriaSpec<DataCenterEmissionSource, DataCenterEmissionSourceCriteria> {
@Override
public Specification<DataCenterEmissionSource> createForAll(DataCenterEmissionSourceCriteria criteria) {
return null;
}
}

View File

@@ -0,0 +1,16 @@
package com.sgs.graphql.dataCenter.repo.criteria.spec;
import com.sgs.graphql.dataCenter.domain.PhysicalMachine;
import com.sgs.graphql.dataCenter.repo.criteria.PhysicalMachineCriteria;
import com.sgs.lib.dao.repo.criteria.spec.BaseCriteriaSpec;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Component;
@Component
public class PhysicalMachineCriteriaSpec extends BaseCriteriaSpec<PhysicalMachine, PhysicalMachineCriteria> {
@Override
public Specification<PhysicalMachine> createForAll(PhysicalMachineCriteria criteria) {
return null;
}
}

View File

@@ -0,0 +1,16 @@
package com.sgs.graphql.dataCenter.repo.criteria.spec;
import com.sgs.graphql.dataCenter.domain.VM;
import com.sgs.graphql.dataCenter.repo.criteria.VMCriteria;
import com.sgs.lib.dao.repo.criteria.spec.BaseCriteriaSpec;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Component;
@Component
public class VMCriteriaSpec extends BaseCriteriaSpec<VM, VMCriteria> {
@Override
public Specification<VM> createForAll(VMCriteria criteria) {
return null;
}
}

View File

@@ -0,0 +1,40 @@
package com.sgs.graphql.dataCenter.service;
import com.sgs.graphql.dataCenter.domain.DataCenter;
import com.sgs.graphql.dataCenter.domain.DataCenterEmissionSource;
import com.sgs.graphql.dataCenter.repo.DataCenterEmissionSourceRepo;
import com.sgs.graphql.dataCenter.repo.criteria.DataCenterEmissionSourceCriteria;
import com.sgs.graphql.dataCenter.repo.criteria.spec.DataCenterEmissionSourceCriteriaSpec;
import com.sgs.lib.dao.service.BaseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;
@Service
public class DataCenterEmissionSourceService extends
BaseService<DataCenterEmissionSource, DataCenterEmissionSourceRepo, DataCenterEmissionSourceCriteria, DataCenterEmissionSourceCriteriaSpec> {
@Autowired
public DataCenterEmissionSourceService(DataCenterEmissionSourceRepo repository,
DataCenterEmissionSourceCriteriaSpec criteriaSpec) {
super(repository, criteriaSpec);
}
public List<DataCenterEmissionSource> findByDataCenter(DataCenter dataCenter) {
return getRepository().findByDataCenter(dataCenter);
}
public Optional<DataCenterEmissionSource> findByDataCenterAndIsDefaultTrue(DataCenter dataCenter) {
return getRepository().findByDataCenterAndIsDefaultTrue(dataCenter);
}
public List<DataCenterEmissionSource> findByDataCenterId(String dataCenterId) {
return getRepository().findByDataCenterId(dataCenterId);
}
public void deleteByDataCenter(DataCenter dataCenter) {
getRepository().deleteByDataCenter(dataCenter);
}
}

View File

@@ -8,8 +8,11 @@ import com.sgs.lib.dao.service.BaseService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.Optional;
@Service @Service
public class DataCenterService extends BaseService<DataCenter, DataCenterRepo, DataCenterCriteria, DataCenterCriteriaSpec> { public class DataCenterService
extends BaseService<DataCenter, DataCenterRepo, DataCenterCriteria, DataCenterCriteriaSpec> {
@Autowired @Autowired
public DataCenterService(DataCenterRepo repository, DataCenterCriteriaSpec criteriaSpec) { public DataCenterService(DataCenterRepo repository, DataCenterCriteriaSpec criteriaSpec) {
@@ -19,4 +22,12 @@ public class DataCenterService extends BaseService<DataCenter, DataCenterRepo, D
public boolean existsByExternalId(Integer externalId) { public boolean existsByExternalId(Integer externalId) {
return getRepository().existsByExternalId(externalId); return getRepository().existsByExternalId(externalId);
} }
public Optional<DataCenter> findByNumber(Integer number) {
return getRepository().findByNumber(number);
}
public Integer findMaxNumber() {
return getRepository().findMaxNumber();
}
} }

View File

@@ -0,0 +1,26 @@
package com.sgs.graphql.dataCenter.service;
import com.sgs.graphql.dataCenter.domain.PhysicalMachine;
import com.sgs.graphql.dataCenter.repo.PhysicalMachineRepo;
import com.sgs.graphql.dataCenter.repo.criteria.PhysicalMachineCriteria;
import com.sgs.graphql.dataCenter.repo.criteria.spec.PhysicalMachineCriteriaSpec;
import com.sgs.lib.dao.service.BaseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.UUID;
@Service
public class PhysicalMachineService extends
BaseService<PhysicalMachine, PhysicalMachineRepo, PhysicalMachineCriteria, PhysicalMachineCriteriaSpec> {
@Autowired
public PhysicalMachineService(PhysicalMachineRepo repository, PhysicalMachineCriteriaSpec criteriaSpec) {
super(repository, criteriaSpec);
}
public List<PhysicalMachine> findByDatacenterId(UUID datacenterId) {
return getRepository().findByDatacenterId(datacenterId);
}
}

View File

@@ -0,0 +1,29 @@
package com.sgs.graphql.dataCenter.service;
import com.sgs.graphql.dataCenter.domain.VM;
import com.sgs.graphql.dataCenter.repo.VMRepo;
import com.sgs.graphql.dataCenter.repo.criteria.VMCriteria;
import com.sgs.graphql.dataCenter.repo.criteria.spec.VMCriteriaSpec;
import com.sgs.lib.dao.service.BaseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;
@Service
public class VMService extends BaseService<VM, VMRepo, VMCriteria, VMCriteriaSpec> {
@Autowired
public VMService(VMRepo repository, VMCriteriaSpec criteriaSpec) {
super(repository, criteriaSpec);
}
public List<VM> findAllByVmName(String vmName) {
return getRepository().findAllByVmName(vmName);
}
public Optional<VM> findFirstByVmNameOrderByIdDesc(String vmName) {
return getRepository().findFirstByVmNameOrderByIdDesc(vmName);
}
}

View File

@@ -22,7 +22,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@Service @Service
public class MainDataTableService extends BaseService<MainDataTable, MainDataTableRepo, MainDataTableCriteria, MainDataTableCriteriaSpec> { public class MainDataTableService
extends BaseService<MainDataTable, MainDataTableRepo, MainDataTableCriteria, MainDataTableCriteriaSpec> {
@PersistenceContext @PersistenceContext
private EntityManager entityManager; private EntityManager entityManager;
@@ -112,6 +113,7 @@ public class MainDataTableService extends BaseService<MainDataTable, MainDataTab
/** /**
* Converts PostgreSQL hex format UUID to proper UUID format * Converts PostgreSQL hex format UUID to proper UUID format
*
* @param hexUuid UUID in hex format (e.g., \x6205c18b8d1e4f0fa5154212fb44050b) * @param hexUuid UUID in hex format (e.g., \x6205c18b8d1e4f0fa5154212fb44050b)
* @return UUID object * @return UUID object
*/ */
@@ -122,10 +124,10 @@ public class MainDataTableService extends BaseService<MainDataTable, MainDataTab
// Insert hyphens to make it a proper UUID format // Insert hyphens to make it a proper UUID format
// UUID format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx // UUID format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
String formatted = hex.substring(0, 8) + "-" + String formatted = hex.substring(0, 8) + "-" +
hex.substring(8, 12) + "-" + hex.substring(8, 12) + "-" +
hex.substring(12, 16) + "-" + hex.substring(12, 16) + "-" +
hex.substring(16, 20) + "-" + hex.substring(16, 20) + "-" +
hex.substring(20); hex.substring(20);
return UUID.fromString(formatted); return UUID.fromString(formatted);
} else { } else {
// If it's already in proper format, parse directly // If it's already in proper format, parse directly

View File

@@ -839,7 +839,7 @@ public class MessageListener {
System.out.println("🔍 Setting VM ID: " + vm.getId()); System.out.println("🔍 Setting VM ID: " + vm.getId());
// Use the source-specific power consumption (percentage of total VM power) // Use the source-specific power consumption (percentage of total VM power)
// Format to 6 decimal places to avoid very long strings // Format to 6 decimal places to avoid very long strings
String formattedPower = String.format("%.6f", sourceSpecificPower); String formattedPower = String.format("%.6f", sourceSpecificPower);
input.setConsuptionAmount(formattedPower); input.setConsuptionAmount(formattedPower);
System.out.println("🔍 Setting Consumption Amount: " + formattedPower + "W"); System.out.println("🔍 Setting Consumption Amount: " + formattedPower + "W");
@@ -850,6 +850,7 @@ public class MessageListener {
System.out.println(" Month: " + (input.getMonth() != null ? input.getMonth().length() : "null")); System.out.println(" Month: " + (input.getMonth() != null ? input.getMonth().length() : "null"));
System.out.println(" ConsuptionAmount: " + (input.getConsuptionAmount() != null ? input.getConsuptionAmount().length() : "null")); System.out.println(" ConsuptionAmount: " + (input.getConsuptionAmount() != null ? input.getConsuptionAmount().length() : "null"));
System.out.println("🔍 VM Emission Input for Source:"); System.out.println("🔍 VM Emission Input for Source:");
System.out.println(" VM ID: " + vm.getId()); System.out.println(" VM ID: " + vm.getId());
System.out.println(" VM Name: " + vm.getVmName()); System.out.println(" VM Name: " + vm.getVmName());

View File

@@ -17,16 +17,10 @@ security.jwt.token.secret-key=secret
app.survey.base-url=http://localhost.com app.survey.base-url=http://localhost.com
# spring.rabbitmq.host=188.132.198.145 spring.rabbitmq.host=188.132.198.145
# spring.rabbitmq.port=5672
# spring.rabbitmq.username=testuser
# spring.rabbitmq.password=JGasF24561AZv2894De
#spring.rabbitmq.host=rabbitmq
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672 spring.rabbitmq.port=5672
spring.rabbitmq.username=guest spring.rabbitmq.username=testuser
spring.rabbitmq.password=guest spring.rabbitmq.password=JGasF24561AZv2894De
spring.rabbitmq.virtual-host=/ spring.rabbitmq.virtual-host=/
spring.rabbitmq.connection-timeout=20000 spring.rabbitmq.connection-timeout=20000
spring.rabbitmq.template.retry.enabled=true spring.rabbitmq.template.retry.enabled=true
@@ -34,3 +28,6 @@ spring.rabbitmq.template.retry.max-attempts=3
spring.rabbitmq.template.retry.initial-interval=1000ms spring.rabbitmq.template.retry.initial-interval=1000ms
logging.level.org.springframework.amqp=DEBUG logging.level.org.springframework.amqp=DEBUG
spring.jpa.show-sql=true
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE

View File

@@ -102,3 +102,7 @@ Ensure both services are configured consistently.
## License ## License
[Insert your license information here] [Insert your license information here]
## CI/CD Testing v20

View File

@@ -1,35 +1,28 @@
server { server {
listen 80; listen 80;
server_name bgreen.blc-css.com; server_name bgreen.blc-css.com;
root /usr/share/nginx/html; root /usr/share/nginx/html;
index index.html index.htm; index index.html index.htm;
location / { location / {
try_files $uri /index.html; try_files $uri /index.html;
} }
location /api/v1/graphql { location /api/v1/graphql {
proxy_pass http://bgreen-backend:8080/api/v1/graphql; proxy_pass http://bgreen-backend:8080/api/v1/graphql;
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
} }
location /api/v1/upload { location /api/v1/upload {
proxy_pass http://bgreen-backend:8080/upload; proxy_pass http://bgreen-backend:8080/upload;
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
} }
# location /api/v1/datacenter { # location /api/v1/datacenter {
# proxy_pass http://backend:8080/api/v1/datacenter; # proxy_pass http://backend:8080/api/v1/datacenter;
# proxy_set_header Host $host; # proxy_set_header Host $host;
# proxy_set_header X-Real-IP $remote_addr; # proxy_set_header X-Real-IP $remote_addr;
# } # }
# Hata durumlarında da index.html'i sun # Hata durumlarında da index.html'i sun
error_page 404 /index.html; error_page 404 /index.html;
gzip on; gzip on;
gzip_vary on; gzip_vary on;
gzip_min_length 10240; gzip_min_length 10240;

View File

@@ -1,6 +1,6 @@
{ {
"name": "sgs-web", "name": "sgs-web",
"version": "1.0.0", "version": "1.0.2",
"private": true, "private": true,
"dependencies": { "dependencies": {
"@apollo/client": "^3.13.8", "@apollo/client": "^3.13.8",

View File

@@ -67,7 +67,11 @@
"Common": { "Common": {
"save": "Save", "save": "Save",
"cancel": "Cancel" "cancel": "Cancel",
"yes": "Yes",
"no": "No",
"areYouSure": "Are you sure?",
"cantRevert": "This action cannot be undone!"
}, },
"DataInput": { "DataInput": {

View File

@@ -66,7 +66,11 @@
"Common": { "Common": {
"save": "Kaydet", "save": "Kaydet",
"cancel": " İptal" "cancel": "İptal",
"yes": "Evet",
"no": "Hayır",
"areYouSure": "Emin misiniz?",
"cantRevert": "Bu işlem geri alınamaz!"
}, },
"DataInput": { "DataInput": {

View File

@@ -49,9 +49,9 @@ export default [
permissionCheck("paginate_roles_get")) && [ permissionCheck("paginate_roles_get")) && [
{ {
id: "Organizations", id: "Organizations",
title: "DataCenters.title", title: "Data Center Management",
icon: <Home size={20} />, icon: <Home size={20} />,
navLink: "/organizasyonlar", navLink: "/veri-merkezi-yonetimi",
display: (permissionCheck("paginate_datacenters_get") || display: (permissionCheck("paginate_datacenters_get") ||
permissionCheck("data_center_create") || permissionCheck("data_center_create") ||
permissionCheck("data_center_update") || permissionCheck("data_center_update") ||
@@ -142,9 +142,63 @@ export default [
}, },
{ {
id: "DataCenter", id: "DataCenter",
title: "Data Centers", title: "Data Center Overview",
icon: <Zap size={20} />, icon: <Zap size={20} />,
navLink: "/verimerkezi", navLink: "/veri-merkezi-genel",
},
{
id: "Areas",
title: "Areas.areas",
icon: <Map size={20} />,
display:
permissionCheck("paginate_areas_get") ||
permissionCheck("paginate_countries_get") ||
permissionCheck("paginate_cities_get") ||
permissionCheck("paginate_districts_get") ||
permissionCheck("paginate_neighborhoods_get")
? ""
: "none",
children: (permissionCheck("paginate_areas_get") ||
permissionCheck("paginate_countries_get") ||
permissionCheck("paginate_cities_get") ||
permissionCheck("paginate_districts_get") ||
permissionCheck("paginate_neighborhoods_get")) && [
{
id: "AreasManagement",
title: "Areas.areas",
icon: <ArrowRight size={20} />,
navLink: "/alanlar",
display: permissionCheck("paginate_areas_get") ? "" : "none",
},
{
id: "Countries",
title: "Areas.countries",
icon: <ArrowRight size={20} />,
navLink: "/ulkeler",
display: permissionCheck("paginate_countries_get") ? "" : "none",
},
{
id: "Cities",
title: "Areas.cities",
icon: <ArrowRight size={20} />,
navLink: "/iller",
display: permissionCheck("paginate_cities_get") ? "" : "none",
},
{
id: "Districts",
title: "Areas.districts",
icon: <ArrowRight size={20} />,
navLink: "/ilceler",
display: permissionCheck("paginate_districts_get") ? "" : "none",
},
{
id: "Neighborhoods",
title: "Areas.neighborhoods",
icon: <ArrowRight size={20} />,
navLink: "/mahalleler",
display: permissionCheck("paginate_neighborhoods_get") ? "" : "none",
},
],
}, },
{ {
id: "Survey", id: "Survey",

View File

@@ -49,9 +49,9 @@ export default [
permissionCheck("paginate_roles_get")) && [ permissionCheck("paginate_roles_get")) && [
{ {
id: "DataCenters", id: "DataCenters",
title: "DataCenters.title", title: "Data Center Management",
icon: <Zap size={20} />, icon: <Zap size={20} />,
navLink: "/organizasyonlar", navLink: "/veri-merkezi-yonetimi",
display: (permissionCheck("paginate_datacenters_get") || display: (permissionCheck("paginate_datacenters_get") ||
permissionCheck("data_center_create") || permissionCheck("data_center_create") ||
permissionCheck("data_center_update") || permissionCheck("data_center_update") ||
@@ -142,9 +142,63 @@ export default [
}, },
{ {
id: "DataCenter", id: "DataCenter",
title: "DataCenters", title: "Data Center Overview",
icon: <Zap size={20} />, icon: <Zap size={20} />,
navLink: "/verimerkezi", navLink: "/veri-merkezi-genel",
},
{
id: "Areas",
title: "Areas.areas",
icon: <Map size={20} />,
display:
permissionCheck("paginate_areas_get") ||
permissionCheck("paginate_countries_get") ||
permissionCheck("paginate_cities_get") ||
permissionCheck("paginate_districts_get") ||
permissionCheck("paginate_neighborhoods_get")
? ""
: "none",
children: (permissionCheck("paginate_areas_get") ||
permissionCheck("paginate_countries_get") ||
permissionCheck("paginate_cities_get") ||
permissionCheck("paginate_districts_get") ||
permissionCheck("paginate_neighborhoods_get")) && [
{
id: "AreasManagement",
title: "Areas.areas",
icon: <ArrowRight size={20} />,
navLink: "/alanlar",
display: permissionCheck("paginate_areas_get") ? "" : "none",
},
{
id: "Countries",
title: "Areas.countries",
icon: <ArrowRight size={20} />,
navLink: "/ulkeler",
display: permissionCheck("paginate_countries_get") ? "" : "none",
},
{
id: "Cities",
title: "Areas.cities",
icon: <ArrowRight size={20} />,
navLink: "/iller",
display: permissionCheck("paginate_cities_get") ? "" : "none",
},
{
id: "Districts",
title: "Areas.districts",
icon: <ArrowRight size={20} />,
navLink: "/ilceler",
display: permissionCheck("paginate_districts_get") ? "" : "none",
},
{
id: "Neighborhoods",
title: "Areas.neighborhoods",
icon: <ArrowRight size={20} />,
navLink: "/mahalleler",
display: permissionCheck("paginate_neighborhoods_get") ? "" : "none",
},
],
}, },
{ {
id: "Survey", id: "Survey",

View File

@@ -12,6 +12,15 @@ export const getAreas = () => {
id id
tag tag
isDeleted isDeleted
cities {
id
name
coordinates
country {
id
name
}
}
} }
} }
`, `,

View File

@@ -34,30 +34,69 @@ export const getDataCenters = () => {
latitude latitude
longitude longitude
area { area {
tag
name
cityId
districtId
}
projects {
id id
name tag
physicalMachines { cities {
id id
name name
vms { }
active { districts {
id id
status name
name }
power }
config { city {
id id
cpu name
ram }
disk emissionScope {
} id
} tag
description
}
sector {
id
tag
}
subSector {
id
tag
}
dataCenterEmissionSources {
id
emissionSource {
id
tag
}
consuptionUnit {
id
description
}
isDefault
percentage
}
activitySubUnit {
id
tag
}
physicalMachines {
id
name
vms {
id
vmName
state
power
calcOn
hostingPm
host
flavorName
tag
config {
id
cpu
ram
disk
} }
} }
} }
@@ -77,7 +116,7 @@ export const getDataCenters = () => {
console.log("GraphQL Response:", { console.log("GraphQL Response:", {
status: response.status, status: response.status,
data: response.data, data: response.data,
errors: response.data?.errors errors: response.data?.errors,
}); });
// Check for GraphQL errors // Check for GraphQL errors
@@ -110,7 +149,7 @@ export const getDataCenters = () => {
message: error.message, message: error.message,
response: error.response?.data, response: error.response?.data,
status: error.response?.status, status: error.response?.status,
stack: error.stack stack: error.stack,
}); });
// Check for specific error types // Check for specific error types
@@ -155,10 +194,50 @@ export const createDataCenter = (dataCenterData) => {
latitude latitude
longitude longitude
area { area {
id
tag tag
cities {
id
name
}
districts {
id
name
}
}
city {
id
name name
cityId }
districtId emissionScope {
id
tag
description
}
sector {
id
tag
}
subSector {
id
tag
}
dataCenterEmissionSources {
id
emissionSource {
id
tag
}
consuptionUnit {
id
description
}
isDefault
percentage
}
activitySubUnit {
id
tag
} }
} }
} }
@@ -169,13 +248,23 @@ export const createDataCenter = (dataCenterData) => {
externalId: parseInt(dataCenterData.externalId), externalId: parseInt(dataCenterData.externalId),
ayposURL: dataCenterData.ayposURL || "", ayposURL: dataCenterData.ayposURL || "",
number: parseInt(dataCenterData.number) || 1, number: parseInt(dataCenterData.number) || 1,
areaId: dataCenterData.areaId, areaId: dataCenterData.areaId || null,
cityId: dataCenterData.cityId || null,
address: dataCenterData.address || "", address: dataCenterData.address || "",
latitude: dataCenterData.latitude ? parseFloat(dataCenterData.latitude) : null, latitude: dataCenterData.latitude
longitude: dataCenterData.longitude ? parseFloat(dataCenterData.longitude) : null, ? parseFloat(dataCenterData.latitude)
city: dataCenterData.city : null,
} longitude: dataCenterData.longitude
} ? parseFloat(dataCenterData.longitude)
: null,
emissionScopeId: dataCenterData.emissionScopeId || null,
sectorId: dataCenterData.sectorId || null,
subSectorId: dataCenterData.subSectorId || null,
dataCenterEmissionSources:
dataCenterData.dataCenterEmissionSources || [],
activitySubUnitId: dataCenterData.activitySubUnitId || null,
},
},
}, },
{ {
headers: { headers: {
@@ -188,7 +277,7 @@ export const createDataCenter = (dataCenterData) => {
console.log("Create Response:", { console.log("Create Response:", {
status: response.status, status: response.status,
data: response.data, data: response.data,
errors: response.data?.errors errors: response.data?.errors,
}); });
if (response.data?.errors) { if (response.data?.errors) {
@@ -240,10 +329,50 @@ export const updateDataCenter = (id, dataCenterData) => {
latitude latitude
longitude longitude
area { area {
id
tag tag
cities {
id
name
}
districts {
id
name
}
}
city {
id
name name
cityId }
districtId emissionScope {
id
tag
description
}
sector {
id
tag
}
subSector {
id
tag
}
dataCenterEmissionSources {
id
emissionSource {
id
tag
}
consuptionUnit {
id
description
}
isDefault
percentage
}
activitySubUnit {
id
tag
} }
} }
} }
@@ -255,13 +384,23 @@ export const updateDataCenter = (id, dataCenterData) => {
externalId: parseInt(dataCenterData.externalId), externalId: parseInt(dataCenterData.externalId),
ayposURL: dataCenterData.ayposURL || "", ayposURL: dataCenterData.ayposURL || "",
number: parseInt(dataCenterData.number) || 1, number: parseInt(dataCenterData.number) || 1,
areaId: dataCenterData.areaId, areaId: dataCenterData.areaId || null,
cityId: dataCenterData.cityId || null,
address: dataCenterData.address || "", address: dataCenterData.address || "",
latitude: dataCenterData.latitude ? parseFloat(dataCenterData.latitude) : null, latitude: dataCenterData.latitude
longitude: dataCenterData.longitude ? parseFloat(dataCenterData.longitude) : null, ? parseFloat(dataCenterData.latitude)
city: dataCenterData.city : null,
} longitude: dataCenterData.longitude
} ? parseFloat(dataCenterData.longitude)
: null,
emissionScopeId: dataCenterData.emissionScopeId || null,
sectorId: dataCenterData.sectorId || null,
subSectorId: dataCenterData.subSectorId || null,
dataCenterEmissionSources:
dataCenterData.dataCenterEmissionSources || [],
activitySubUnitId: dataCenterData.activitySubUnitId || null,
},
},
}, },
{ {
headers: { headers: {
@@ -276,7 +415,7 @@ export const updateDataCenter = (id, dataCenterData) => {
dispatch({ dispatch({
type: "UPDATE_DATA_CENTER_SUCCESS", type: "UPDATE_DATA_CENTER_SUCCESS",
payload: response.data.data.updateDataCenter payload: response.data.data.updateDataCenter,
}); });
return response.data.data.updateDataCenter; return response.data.data.updateDataCenter;
@@ -309,8 +448,8 @@ export const deleteDataCenter = (id) => {
} }
`, `,
variables: { variables: {
id: id id: id,
} },
}, },
{ {
headers: { headers: {
@@ -325,7 +464,7 @@ export const deleteDataCenter = (id) => {
dispatch({ dispatch({
type: "DELETE_DATA_CENTER_SUCCESS", type: "DELETE_DATA_CENTER_SUCCESS",
payload: id payload: id,
}); });
return true; return true;
@@ -342,69 +481,113 @@ export const deleteDataCenter = (id) => {
}; };
}; };
export const getEmissionScopes = () => {
return async (dispatch) => {
dispatch({
type: "GET_EMISSION_SCOPES_LOADING",
});
try {
const response = await ApplicationService.http().post(
"/graphql",
{
query: `
query GetEmissionScopes {
emissionScopes {
id
tag
description
}
}
`,
},
{
headers: {
Authorization: "Bearer " + localStorage.getItem("accessToken"),
},
}
);
if (response.data?.errors) {
throw new Error(response.data.errors[0].message);
}
dispatch({
type: "GET_EMISSION_SCOPES_SUCCESS",
payload: response.data.data.emissionScopes,
});
return response.data.data.emissionScopes;
} catch (error) {
console.error("Error fetching emission scopes:", error);
dispatch({
type: "GET_EMISSION_SCOPES_ERROR",
payload: {
error: error.message || "Failed to fetch emission scopes",
},
});
throw error;
}
};
};
export const getDataCenterVMs = (dataCenterId) => { export const getDataCenterVMs = (dataCenterId) => {
return new Promise(async (resolve, reject) => { return new Promise(async (resolve, reject) => {
// Don't make the request if dataCenterId is undefined, null, or empty // Don't make the request if dataCenterId is undefined, null, or empty
if (!dataCenterId || dataCenterId === "undefined") { if (!dataCenterId || dataCenterId === "undefined") {
console.log('getDataCenterVMs: No dataCenterId provided'); console.log("getDataCenterVMs: No dataCenterId provided");
resolve([]); resolve([]);
return; return;
} }
try { try {
console.log('getDataCenterVMs: Fetching VMs for data center:', dataCenterId); console.log(
const response = await ApplicationService.http() "getDataCenterVMs: Fetching VMs for data center:",
.post( dataCenterId
"/graphql", );
{ const response = await ApplicationService.http().post(
query: ` "/graphql",
{
query: `
{ {
dataCenter(id: "${dataCenterId}") { dataCenter(id: "${dataCenterId}") {
id id
dataCenter dataCenter
projects { physicalMachines {
id id
name name
physicalMachines { vms {
id id
name vmName
vms { state
id power
name
status
power
}
} }
} }
} }
} }
`, `,
},
{
headers: {
Authorization: "Bearer " + localStorage.getItem("accessToken"),
}, },
{ }
headers: { );
Authorization: "Bearer " + localStorage.getItem("accessToken"),
},
}
);
const dataCenter = response?.data?.data?.dataCenter; const dataCenter = response?.data?.data?.dataCenter;
console.log('getDataCenterVMs: Data center response:', dataCenter); console.log("getDataCenterVMs: Data center response:", dataCenter);
let allVMs = []; let allVMs = [];
if (dataCenter && dataCenter.projects) { if (dataCenter && dataCenter.physicalMachines) {
dataCenter.projects.forEach(project => { dataCenter.physicalMachines.forEach((pm) => {
if (project.physicalMachines) { if (pm.vms) {
project.physicalMachines.forEach(pm => { allVMs = allVMs.concat(pm.vms);
if (pm.vms) {
allVMs = allVMs.concat(pm.vms);
}
});
} }
}); });
} }
console.log('getDataCenterVMs: Found VMs:', allVMs); console.log("getDataCenterVMs: Found VMs:", allVMs);
resolve(allVMs); resolve(allVMs);
} catch (error) { } catch (error) {
console.error("Error fetching VMs by data center:", error); console.error("Error fetching VMs by data center:", error);

View File

@@ -1,6 +1,6 @@
import ApplicationService from "../../../services/ApplicationService"; import ApplicationService from "../../../services/ApplicationService";
export const getVMEmissionSummary = () => { export const getVMEmissionSummary = (datacenterId) => {
return async (dispatch) => { return async (dispatch) => {
try { try {
const response = await ApplicationService.http() const response = await ApplicationService.http()
@@ -8,8 +8,8 @@ export const getVMEmissionSummary = () => {
"/graphql", "/graphql",
{ {
query: ` query: `
{ query GetVMEmissions($datacenterId: ID) {
vmEmissionSummary { vmEmissionSummary(datacenterId: $datacenterId) {
vmId vmId
vmName vmName
vmPower vmPower
@@ -17,7 +17,7 @@ export const getVMEmissionSummary = () => {
totalEmission totalEmission
createdDate createdDate
physicalMachine physicalMachine
project cloudSystem
dataCenter dataCenter
co2 co2
ch4 ch4
@@ -25,7 +25,10 @@ export const getVMEmissionSummary = () => {
reportGeneratedTime reportGeneratedTime
} }
} }
` `,
variables: {
datacenterId: datacenterId
}
}, },
{ {
headers: { headers: {
@@ -125,11 +128,12 @@ export const getMainDataTablesWithPaginate = (data) => {
{ {
paginateMainDataTables( paginateMainDataTables(
pagination: { page: 0, rowsPerPage: 100 } pagination: { page: 0, rowsPerPage: 100 }
criteria: { deleted: false } criteria: { deleted: false, hasVm: true }
sortBy: [{ field: "createdDate", direction: DESC }] sortBy: [{ field: "createdDate", direction: DESC }]
) { ) {
content { content {
id id
year
sector { sector {
id id
tag tag
@@ -138,11 +142,40 @@ export const getMainDataTablesWithPaginate = (data) => {
id id
tag tag
} }
activitySubUnit {
id
tag
}
emissionSource {
id
tag
}
emissionScope {
id
tag
}
co2 co2
ch4 ch4
n2o n2o
totalEmission totalEmission
createdDate createdDate
vm {
id
vmName
state
power
calcOn
hostingPm
host
flavorName
tag
config {
id
cpu
ram
disk
}
}
} }
pageInfo { pageInfo {
totalElements totalElements

View File

@@ -0,0 +1,33 @@
const initialState = {
emissionScopes: [],
loading: false,
error: null,
};
const emissionScopeReducer = (state = initialState, action) => {
switch (action.type) {
case "GET_EMISSION_SCOPES_LOADING":
return {
...state,
loading: true,
error: null,
};
case "GET_EMISSION_SCOPES_SUCCESS":
return {
...state,
loading: false,
emissionScopes: action.payload,
error: null,
};
case "GET_EMISSION_SCOPES_ERROR":
return {
...state,
loading: false,
error: action.payload.error,
};
default:
return state;
}
};
export default emissionScopeReducer;

View File

@@ -27,6 +27,7 @@ import surveys from "./surveys";
import uploads from "./upload"; import uploads from "./upload";
import mailSettings from "./mailSettings"; import mailSettings from "./mailSettings";
import dataCenter from "./dataCenter"; import dataCenter from "./dataCenter";
import emissionScope from "./emissionScope";
const rootReducer = combineReducers({ const rootReducer = combineReducers({
accessToken, accessToken,
@@ -57,6 +58,7 @@ const rootReducer = combineReducers({
uploads, uploads,
mailSettings, mailSettings,
dataCenter, dataCenter,
emissionScope,
}); });
export default rootReducer; export default rootReducer;

View File

@@ -25,7 +25,7 @@ const Routes = [
display: permissionCheck("paginate_users_get"), display: permissionCheck("paginate_users_get"),
}, },
{ {
path: "/organizasyonlar", path: "/veri-merkezi-yonetimi",
component: lazy(() => import("../../views/DataCenterManagement")), component: lazy(() => import("../../views/DataCenterManagement")),
display: permissionCheck("paginate_datacenters_get") || display: permissionCheck("paginate_datacenters_get") ||
permissionCheck("data_center_create") || permissionCheck("data_center_create") ||
@@ -74,7 +74,7 @@ const Routes = [
display: permissionCheck("activity_sub_units_get"), display: permissionCheck("activity_sub_units_get"),
}, },
{ {
path: "/verimerkezi", path: "/veri-merkezi-genel",
component: lazy(() => import("../../views/DataCenter")), component: lazy(() => import("../../views/DataCenter")),
}, },
{ {

View File

@@ -75,7 +75,7 @@ const Areas = () => {
}, },
{ {
name: t("Areas.areas"), name: t("Areas.areas"),
selector: (row) => row.areas, // Bura boştu "". selector: (row) => row.areas, // Bura boştu "".
sortable: true, sortable: true,
minWidth: "350px", minWidth: "350px",
cell: (row) => { cell: (row) => {

View File

@@ -9,7 +9,7 @@ import {
ModalBody, ModalBody,
ModalHeader, ModalHeader,
Row, Row,
UncontrolledTooltip, // Add UncontrolledTooltip import UncontrolledTooltip, // Add UncontrolledTooltip import
} from "reactstrap"; } from "reactstrap";
import { Edit, Mail, Phone, MapPin } from "react-feather"; // Import Mail, Phone, MapPin import { Edit, Mail, Phone, MapPin } from "react-feather"; // Import Mail, Phone, MapPin
@@ -187,7 +187,7 @@ function Communication() {
{/* Add MapPin icon */} {/* Add MapPin icon */}
<address> <address>
Central Office: 4995 sokak no:3, Alacaatlı Mahallesi, Central Office: 4995 sokak no:3, Alacaatlı Mahallesi,
Daire No: A2 06810 Çankaya/Ankara Daire No: A2 06820 Çankaya/Ankara
</address> </address>
</div> </div>
</Col> </Col>

View File

@@ -18,17 +18,16 @@ const DataCenter = () => {
const [refreshInterval, setRefreshInterval] = useState(null); const [refreshInterval, setRefreshInterval] = useState(null);
const getAllPhysicalMachines = (dataCenter) => { const getAllPhysicalMachines = (dataCenter) => {
if (!dataCenter.projects) return []; // Physical machines are directly in the dataCenter object, not in projects
return dataCenter.projects.flatMap(project => const pms = dataCenter.physicalMachines || [];
project.physicalMachines || [] return pms;
);
}; };
// Table columns following your pattern // Table columns following your pattern
const initialColumns = [ const initialColumns = [
{ {
name: "Number", name: "External ID",
selector: (row) => row.number, selector: (row) => row.externalId,
sortable: true, sortable: true,
minWidth: "100px", minWidth: "100px",
}, },
@@ -38,19 +37,33 @@ const DataCenter = () => {
sortable: true, sortable: true,
minWidth: "200px", minWidth: "200px",
}, },
// Projects // Projects - Based on API response, this field might not exist or be structured differently
{ // {
name: "Projects", // name: "Projects",
selector: (row) => // selector: (row) => row.projects?.length || 0,
(row.projects || []).map((p) => p.name).join(", "), // sortable: true,
sortable: false, // minWidth: "200px",
minWidth: "200px", // cell: (row) => (
cell: (row) => ( // <div>
<span> // {row.projects && row.projects.length > 0 ? (
{(row.projects || []).map((p) => p.name).join(", ") || "-"} // <div className="d-flex flex-column">
</span> // {row.projects.map((project, index) => (
), // <div
}, // key={project.id}
// className={`badge badge-light-primary ${
// index > 0 ? "mt-1" : ""
// }`}
// >
// {project.name}
// </div>
// ))}
// </div>
// ) : (
// <span className="text-muted">-</span>
// )}
// </div>
// ),
// },
// Physical Machines // Physical Machines
{ {
name: "Physical Machines", name: "Physical Machines",
@@ -68,26 +81,55 @@ const DataCenter = () => {
}, },
}, },
{ {
name: "Total Active VMs", name: "Virtual Machines",
selector: (row) => { selector: (row) => {
const pms = getAllPhysicalMachines(row); const pms = getAllPhysicalMachines(row);
return pms.reduce( const vms = pms.reduce(
(total, pm) => total + (pm.vms?.active?.length || 0), (acc, pm) => {
0 if (!pm.vms) return acc;
return {
active:
acc.active +
pm.vms.filter((vm) => vm.state?.toLowerCase() === "active")
.length,
total: acc.total + pm.vms.length,
};
},
{ active: 0, total: 0 }
); );
return vms.total;
}, },
sortable: true, sortable: true,
minWidth: "150px", minWidth: "200px",
cell: (row) => { cell: (row) => {
const pms = getAllPhysicalMachines(row); const pms = getAllPhysicalMachines(row);
const totalVMs = pms.reduce( const vms = pms.reduce(
(total, pm) => total + (pm.vms?.active?.length || 0), (acc, pm) => {
0 if (!pm.vms) return acc;
return {
active:
acc.active +
pm.vms.filter((vm) => vm.state?.toLowerCase() === "active")
.length,
total: acc.total + pm.vms.length,
};
},
{ active: 0, total: 0 }
); );
return ( return (
<div className="d-flex align-items-center"> <div className="d-flex align-items-center">
<Monitor size={16} className="mr-1" /> <Monitor size={16} className="mr-2" />
<span>{totalVMs}</span> <div>
<div className="font-weight-bold">{vms.total} Total</div>
<div className="small">
<span className="text-success">{vms.active} Active</span>
<span className="text-muted mx-1"></span>
<span className="text-warning">
{vms.total - vms.active} Inactive
</span>
</div>
</div>
</div> </div>
); );
}, },
@@ -138,76 +180,112 @@ const DataCenter = () => {
<div key={pm.id} className="mb-3 border rounded p-3"> <div key={pm.id} className="mb-3 border rounded p-3">
<h6 className="text-primary">{pm.name}</h6> <h6 className="text-primary">{pm.name}</h6>
{/* Active VMs */} {/* All VMs */}
<p className="mb-2"> <div className="mb-2 d-flex justify-content-between align-items-center">
<strong>Active VMs ({pm.vms?.active?.length || 0}):</strong> <h6 className="mb-0">
</p> <Monitor size={16} className="mr-1" />
{pm.vms?.active?.length > 0 ? ( Virtual Machines ({pm.vms?.length || 0})
<div className="ml-3"> </h6>
{pm.vms.active.map((vm) => ( </div>
<div {pm.vms?.length > 0 ? (
key={vm.id} <div className="table-responsive mt-2">
className="mb-2 p-2 border-left border-success" <table className="table table-bordered table-hover">
> <thead className="thead-light">
<div className="row"> <tr>
<div className="col-md-3"> <th>Name</th>
<strong>Name:</strong> {vm.name} <th>Status</th>
</div> <th>Power (W)</th>
<div className="col-md-2"> <th>Configuration</th>
<strong>Status:</strong> <th>Host</th>
<span className="badge badge-success ml-1"> </tr>
{vm.status} </thead>
</span> <tbody>
</div> {pm.vms.map((vm) => {
<div className="col-md-2"> const isActive =
<strong>Power:</strong> {vm.power} vm.state && ["ACTIVE", "active"].includes(vm.state);
</div> return (
<div className="col-md-5"> <tr key={vm.id}>
<strong>Config:</strong> CPU: {vm.config?.cpu}, RAM:{" "} <td>
{vm.config?.ram}, Disk: {vm.config?.disk} <span className="font-weight-bold">
</div> {vm.vmName || vm.vm_name}
</div> </span>
</div> </td>
))} <td>
<div
className={`d-inline-block px-2 py-1 rounded-pill ${
isActive
? "bg-light-success text-success"
: "bg-light-warning text-warning"
}`}
>
{vm.state}
</div>
</td>
<td>
{vm.power ? (
<span>{vm.power.toFixed(2)}</span>
) : (
<span className="text-muted">-</span>
)}
</td>
<td>
<div className="d-flex align-items-center">
<div className="mr-3">
<small className="text-muted d-block">
CPU
</small>
<span>
{vm.config?.cpu ||
(vm.confg && vm.confg[1]) ||
"-"}
</span>
</div>
<div className="mr-3">
<small className="text-muted d-block">
RAM
</small>
<span>
{vm.config?.ram ||
(vm.confg && vm.confg[2]) ||
"-"}{" "}
GB
</span>
</div>
<div>
<small className="text-muted d-block">
Disk
</small>
<span>
{vm.config?.disk ||
(vm.confg && vm.confg[3]) ||
"-"}{" "}
GB
</span>
</div>
</div>
</td>
<td>
<div className="d-flex align-items-center">
<Server size={14} className="mr-1" />
<span>
{vm.host ||
vm.hostingPm ||
(vm.confg && vm.confg[4]) ||
"-"}
</span>
</div>
</td>
</tr>
);
})}
</tbody>
</table>
</div> </div>
) : ( ) : (
<p className="text-muted ml-3">No active VMs</p> <div className="text-center p-3 bg-light-secondary rounded">
)} <Monitor size={24} className="text-muted mb-1" />
<p className="text-muted mb-0">No virtual machines found</p>
{/* Inactive VMs */}
<p className="mb-2 mt-3">
<strong>Inactive VMs ({pm.vms?.inactive?.length || 0}):</strong>
</p>
{pm.vms?.inactive?.length > 0 ? (
<div className="ml-3">
{pm.vms.inactive.map((vm) => (
<div
key={vm.id}
className="mb-2 p-2 border-left border-warning"
>
<div className="row">
<div className="col-md-3">
<strong>Name:</strong> {vm.name}
</div>
<div className="col-md-2">
<strong>Status:</strong>
<span className="badge badge-warning ml-1">
{vm.status}
</span>
</div>
<div className="col-md-2">
<strong>Power:</strong> {vm.power}
</div>
<div className="col-md-5">
<strong>Config:</strong> CPU: {vm.config?.cpu}, RAM:{" "}
{vm.config?.ram}, Disk: {vm.config?.disk}
</div>
</div>
</div>
))}
</div> </div>
) : (
<p className="text-muted ml-3">No inactive VMs</p>
)} )}
</div> </div>
))} ))}
@@ -215,8 +293,6 @@ const DataCenter = () => {
); );
}; };
return ( return (
<div style={{ marginTop: "2%" }}> <div style={{ marginTop: "2%" }}>
<Card> <Card>

File diff suppressed because it is too large Load Diff

View File

@@ -263,7 +263,7 @@ const EmissionSource = () => {
?.totalElements / rowsPerPage ?.totalElements / rowsPerPage
).toFixed(1) ).toFixed(1)
); );
//asdaasdasd
return ( return (
<ReactPaginate <ReactPaginate
previousLabel={""} previousLabel={""}

View File

@@ -1,101 +1,157 @@
import React, { useState, useEffect } from "react"; import React, { useState, useEffect, useMemo } from "react";
import { MaterialReactTable } from "material-react-table"; import { MaterialReactTable } from "material-react-table";
import { useDispatch, useSelector } from "react-redux"; import { useDispatch, useSelector } from "react-redux";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { Card, CardHeader, CardTitle, Alert } from "reactstrap"; import {
Card,
CardHeader,
CardTitle,
Alert,
Row,
Col,
Label,
} from "reactstrap";
import { getVMEmissionSummary } from "../../redux/actions/mainDataTables/index"; import { getVMEmissionSummary } from "../../redux/actions/mainDataTables/index";
import { getDataCenters } from "../../redux/actions/dataCenter";
import { editNumbers } from "../../components/edit-numbers"; import { editNumbers } from "../../components/edit-numbers";
import Select from "react-select";
function MainDataTables() { function MainDataTables() {
const { t } = useTranslation(); const { t } = useTranslation();
const dispatch = useDispatch(); const dispatch = useDispatch();
const mainDataTablesStore = useSelector((state) => state.mainDataTables); const mainDataTablesStore = useSelector((state) => state.mainDataTables);
const dataCenterStore = useSelector((state) => state.dataCenter);
const [error, setError] = useState(null); const [error, setError] = useState(null);
const [selectedDataCenter, setSelectedDataCenter] = useState(null);
const [dataCenterOptions, setDataCenterOptions] = useState([]);
const [loading, setLoading] = useState(false);
// Fetch datacenters on component mount
useEffect(() => { useEffect(() => {
try { dispatch(getDataCenters());
// Fetch VM emission data
dispatch(getVMEmissionSummary());
} catch (err) {
console.error('Error in MainDataTables:', err);
setError(err.message);
}
}, [dispatch]); }, [dispatch]);
// Debug log for store data // Update datacenter options when datacenters are loaded
useEffect(() => { useEffect(() => {
console.log('Current store data:', mainDataTablesStore); if (dataCenterStore?.dataCenters?.length > 0) {
}, [mainDataTablesStore]); const options = dataCenterStore.dataCenters.map((dataCenter) => ({
value: dataCenter.id,
label: dataCenter.dataCenter,
externalId: dataCenter.externalId,
}));
setDataCenterOptions(options);
}
}, [dataCenterStore?.dataCenters]);
const columns = [ // Fetch VM emission data when datacenter is selected
{ useEffect(() => {
header: "VM ID", if (selectedDataCenter?.value) {
accessorKey: "vmId", const fetchData = async () => {
Cell: ({ cell }) => <span>{cell.getValue() || "-"}</span>, try {
}, setLoading(true);
{ setError(null);
header: "Data Center", await dispatch(getVMEmissionSummary(selectedDataCenter.value));
accessorKey: "dataCenter", } catch (err) {
Cell: ({ cell }) => <span>{cell.getValue() || "-"}</span>, console.error("Error in MainDataTables:", err);
}, setError(err.message);
{ } finally {
header: "Project", setLoading(false);
accessorKey: "project", }
Cell: ({ cell }) => <span>{cell.getValue() || "-"}</span>, };
}, fetchData();
{ }
header: "Physical Machine", }, [selectedDataCenter, dispatch]);
accessorKey: "physicalMachine",
Cell: ({ cell }) => <span>{cell.getValue() || "-"}</span>,
},
{
header: "Virtual Machine",
accessorKey: "vmName",
Cell: ({ cell }) => <span>{cell.getValue() || "-"}</span>,
},
{
header: "VM Power (W)",
accessorKey: "vmPower",
Cell: ({ cell }) => <span>{editNumbers(cell.getValue()) || "-"}</span>,
},
{
header: "VM Status",
accessorKey: "vmStatus",
Cell: ({ cell }) => <span>{cell.getValue() || "-"}</span>,
},
{
header: "Total Emissions",
accessorKey: "totalEmission",
Cell: ({ cell }) => <span>{editNumbers(cell.getValue()) || "-"}</span>,
},
{
header: "CO2",
accessorKey: "co2",
Cell: ({ cell }) => <span>{editNumbers(cell.getValue()) || "-"}</span>,
},
{
header: "CH4",
accessorKey: "ch4",
Cell: ({ cell }) => <span>{editNumbers(cell.getValue()) || "-"}</span>,
},
{
header: "N2O",
accessorKey: "n2o",
Cell: ({ cell }) => <span>{editNumbers(cell.getValue()) || "-"}</span>,
},
{
header: "Created Date",
accessorKey: "createdDate",
Cell: ({ cell }) => (
<span>
{cell.getValue() ? new Date(cell.getValue()).toLocaleString() : "-"}
</span>
),
},
];
const tableData = mainDataTablesStore?.vmEmissionSummary || []; // Memoize columns to prevent re-renders
console.log('VM Emission data:', tableData); const columns = useMemo(
() => [
{
header: t("VM ID"),
accessorKey: "vmId",
size: 150,
Cell: ({ cell }) => <span>{cell.getValue() || "-"}</span>,
},
{
header: t("VM Name"),
accessorKey: "vmName",
size: 200,
Cell: ({ cell }) => <span>{cell.getValue() || "-"}</span>,
},
{
header: t("VM Power"),
accessorKey: "vmPower",
size: 120,
Cell: ({ cell }) => <span>{editNumbers(cell.getValue()) || "-"}</span>,
},
{
header: t("VM Status"),
accessorKey: "vmStatus",
size: 100,
Cell: ({ cell }) => <span>{cell.getValue() || "-"}</span>,
},
{
header: t("Total Emission"),
accessorKey: "totalEmission",
size: 150,
Cell: ({ cell }) => <span>{editNumbers(cell.getValue()) || "-"}</span>,
},
{
header: t("Physical Machine"),
accessorKey: "physicalMachine",
size: 150,
Cell: ({ cell }) => <span>{cell.getValue() || "-"}</span>,
},
{
header: t("Cloud System"),
accessorKey: "cloudSystem",
size: 150,
Cell: ({ cell }) => <span>{cell.getValue() || "-"}</span>,
},
{
header: t("Data Center"),
accessorKey: "dataCenter",
size: 150,
Cell: ({ cell }) => <span>{cell.getValue() || "-"}</span>,
},
{
header: "CO2",
accessorKey: "co2",
size: 100,
Cell: ({ cell }) => <span>{editNumbers(cell.getValue()) || "-"}</span>,
},
{
header: "CH4",
accessorKey: "ch4",
size: 100,
Cell: ({ cell }) => <span>{editNumbers(cell.getValue()) || "-"}</span>,
},
{
header: "N2O",
accessorKey: "n2o",
size: 100,
Cell: ({ cell }) => <span>{editNumbers(cell.getValue()) || "-"}</span>,
},
{
header: t("Created Date"),
accessorKey: "createdDate",
size: 180,
Cell: ({ cell }) => (
<span>
{cell.getValue() ? new Date(cell.getValue()).toLocaleString() : "-"}
</span>
),
sortable: true,
},
],
[t]
);
// Memoize table data to prevent unnecessary re-renders
const tableData = useMemo(() => {
const data = mainDataTablesStore?.vmEmissionSummary || [];
console.log("VM Emission data count:", data.length);
return data;
}, [mainDataTablesStore?.vmEmissionSummary]);
if (error) { if (error) {
return ( return (
@@ -109,37 +165,109 @@ function MainDataTables() {
<div style={{ marginTop: "2%" }}> <div style={{ marginTop: "2%" }}>
<Card> <Card>
<CardHeader className="border-bottom"> <CardHeader className="border-bottom">
<CardTitle tag="h4">{t("Carbon Emission Data")}</CardTitle> <CardTitle tag="h4">{t("Raw Data")}</CardTitle>
{tableData.length > 0 && (
<small className="text-muted">
{tableData.length} records loaded
</small>
)}
</CardHeader> </CardHeader>
<MaterialReactTable
columns={columns} {/* Datacenter Selection */}
data={tableData} <div className="p-3 border-bottom">
enableColumnFilters={true} <Row>
enableFilters={true} <Col md="6">
enableGlobalFilter={true} <Label for="datacenter-select">{t("Data Center")}</Label>
enablePagination={true} <Select
enableColumnResizing={true} id="datacenter-select"
enableStickyHeader={true} value={selectedDataCenter}
muiTableContainerProps={{ sx: { maxHeight: 'calc(100vh - 180px)' } }} onChange={setSelectedDataCenter}
muiTableProps={{ options={dataCenterOptions}
sx: { placeholder={t("Select a data center...")}
tableLayout: 'auto', isClearable
}, isSearchable
}} isLoading={dataCenterStore?.loading}
initialState={{ noOptionsMessage={() => t("No data centers available")}
pagination: { styles={{
pageSize: 100, menu: (provided) => ({
pageIndex: 0 ...provided,
}, zIndex: 9999, // Ensure dropdown appears above other elements
sorting: [ }),
{ id: 'dataCenter', desc: false } }}
], menuPortalTarget={document.body} // Render dropdown in body to avoid container overflow
density: 'compact' />
}} </Col>
state={{ </Row>
isLoading: !mainDataTablesStore?.vmEmissionSummary </div>
}}
/> {selectedDataCenter ? (
<MaterialReactTable
columns={columns}
data={tableData}
// Performance optimizations for large datasets
enableColumnFilters={true}
enableFilters={true}
enableGlobalFilter={true}
enablePagination={true}
enableColumnResizing={true} // Disable resizing for better performance
enableStickyHeader={true}
enableRowVirtualization={true} // Enable virtualization for large datasets
enableColumnVirtualization={false} // Keep columns visible
// Pagination settings for large datasets
initialState={{
pagination: {
pageSize: 100, // Reduce page size for better performance
pageIndex: 0,
},
sorting: [{ id: "createdDate", desc: true }],
density: "compact",
}}
// Performance-optimized table props
muiTableContainerProps={{
sx: {
maxHeight: "calc(100vh - 250px)",
minHeight: "400px",
},
}}
muiTableProps={{
sx: {
tableLayout: "fixed", // Better performance with fixed layout
},
}}
// Pagination options
muiTablePaginationProps={{
rowsPerPageOptions: [10, 25, 50, 100],
showFirstButton: true,
showLastButton: true,
}}
// Loading and error states
state={{
isLoading: loading || mainDataTablesStore?.loading,
showProgressBars: loading || mainDataTablesStore?.loading,
showSkeletons: loading || mainDataTablesStore?.loading,
}}
// Disable features that can slow down large tables
enableRowSelection={false}
enableColumnOrdering={true}
enableColumnDragging={false}
enableDensityToggle={false}
enableFullScreenToggle={false}
// Custom loading overlay
renderProgressBarCell={({ cell }) => (
<div
style={{
width: "100%",
height: "20px",
backgroundColor: "#f0f0f0",
}}
/>
)}
/>
) : (
<div className="p-4 text-center text-muted">
{t("Please select a data center to view raw data")}
</div>
)}
</Card> </Card>
</div> </div>
); );

View File

@@ -32,15 +32,87 @@ import { getCities } from "../redux/actions/cities";
import { v4 as uuidv4 } from "uuid"; import { v4 as uuidv4 } from "uuid";
import { getCity } from "../redux/actions/city"; import { getCity } from "../redux/actions/city";
import { getDistrict } from "../redux/actions/district"; import { getDistrict } from "../redux/actions/district";
import { // import {
getOrganisations, // getOrganisations,
getOrganisationById, // getOrganisationById,
} from "../redux/actions/organisations"; // } from "../redux/actions/organisations";
import { getAreasWithCriteria } from "../redux/actions/areas"; import { getAreasWithCriteria } from "../redux/actions/areas";
import { ChromePicker } from "react-color"; import { ChromePicker } from "react-color";
import { customFilterForSelect } from "../utility/Utils"; import { customFilterForSelect } from "../utility/Utils";
import { permissionCheck } from "../components/permission-check"; import { permissionCheck } from "../components/permission-check";
import { getDataCenters } from "../redux/actions/dataCenter"; import { getDataCenters } from "../redux/actions/dataCenter";
import L from "leaflet";
// Custom data center icon
const dataCenterIcon = new L.Icon({
iconUrl:
"data:image/svg+xml;base64," +
btoa(`
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="48" height="48">
<defs>
<linearGradient id="serverGradient" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#4A90E2;stop-opacity:1" />
<stop offset="100%" style="stop-color:#2E5BBA;stop-opacity:1" />
</linearGradient>
<linearGradient id="rackGradient" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#F5F5F5;stop-opacity:1" />
<stop offset="100%" style="stop-color:#E0E0E0;stop-opacity:1" />
</linearGradient>
</defs>
<!-- Main server rack -->
<rect x="8" y="4" width="32" height="40" rx="2" ry="2" fill="url(#rackGradient)" stroke="#B0B0B0" stroke-width="1"/>
<!-- Server units -->
<rect x="10" y="6" width="28" height="4" rx="1" fill="url(#serverGradient)" stroke="#2E5BBA" stroke-width="0.5"/>
<rect x="10" y="12" width="28" height="4" rx="1" fill="url(#serverGradient)" stroke="#2E5BBA" stroke-width="0.5"/>
<rect x="10" y="18" width="28" height="4" rx="1" fill="url(#serverGradient)" stroke="#2E5BBA" stroke-width="0.5"/>
<rect x="10" y="24" width="28" height="4" rx="1" fill="url(#serverGradient)" stroke="#2E5BBA" stroke-width="0.5"/>
<rect x="10" y="30" width="28" height="4" rx="1" fill="url(#serverGradient)" stroke="#2E5BBA" stroke-width="0.5"/>
<rect x="10" y="36" width="28" height="4" rx="1" fill="url(#serverGradient)" stroke="#2E5BBA" stroke-width="0.5"/>
<!-- LED indicators -->
<circle cx="13" cy="8" r="0.8" fill="#00FF00"/>
<circle cx="13" cy="14" r="0.8" fill="#00FF00"/>
<circle cx="13" cy="20" r="0.8" fill="#FFFF00"/>
<circle cx="13" cy="26" r="0.8" fill="#00FF00"/>
<circle cx="13" cy="32" r="0.8" fill="#FF0000"/>
<circle cx="13" cy="38" r="0.8" fill="#00FF00"/>
<!-- Power indicators -->
<circle cx="35" cy="8" r="0.6" fill="#0080FF"/>
<circle cx="35" cy="14" r="0.6" fill="#0080FF"/>
<circle cx="35" cy="20" r="0.6" fill="#0080FF"/>
<circle cx="35" cy="26" r="0.6" fill="#0080FF"/>
<circle cx="35" cy="32" r="0.6" fill="#0080FF"/>
<circle cx="35" cy="38" r="0.6" fill="#0080FF"/>
<!-- Ventilation grilles -->
<rect x="16" y="7" width="16" height="0.5" fill="#1A4A8A"/>
<rect x="16" y="8.5" width="16" height="0.5" fill="#1A4A8A"/>
<rect x="16" y="13" width="16" height="0.5" fill="#1A4A8A"/>
<rect x="16" y="14.5" width="16" height="0.5" fill="#1A4A8A"/>
<rect x="16" y="19" width="16" height="0.5" fill="#1A4A8A"/>
<rect x="16" y="20.5" width="16" height="0.5" fill="#1A4A8A"/>
<rect x="16" y="25" width="16" height="0.5" fill="#1A4A8A"/>
<rect x="16" y="26.5" width="16" height="0.5" fill="#1A4A8A"/>
<rect x="16" y="31" width="16" height="0.5" fill="#1A4A8A"/>
<rect x="16" y="32.5" width="16" height="0.5" fill="#1A4A8A"/>
<rect x="16" y="37" width="16" height="0.5" fill="#1A4A8A"/>
<rect x="16" y="38.5" width="16" height="0.5" fill="#1A4A8A"/>
<!-- Base/feet -->
<rect x="6" y="42" width="4" height="2" rx="1" fill="#808080"/>
<rect x="38" y="42" width="4" height="2" rx="1" fill="#808080"/>
<!-- Shadow -->
<ellipse cx="24" cy="45" rx="18" ry="2" fill="#000000" opacity="0.2"/>
</svg>
`),
iconSize: [48, 48],
iconAnchor: [18, 36],
popupAnchor: [0, -36],
});
const ColorPicker = ({ selectedColors, setSelectedColors, index }) => { const ColorPicker = ({ selectedColors, setSelectedColors, index }) => {
const [showColorPicker, setShowColorPicker] = useState(false); const [showColorPicker, setShowColorPicker] = useState(false);
@@ -117,20 +189,20 @@ const Map = () => {
const citiesStore = useSelector((state) => state.cities); const citiesStore = useSelector((state) => state.cities);
const cityStore = useSelector((state) => state.city); const cityStore = useSelector((state) => state.city);
const districtStore = useSelector((state) => state.district); const districtStore = useSelector((state) => state.district);
const OrganisationsStore = useSelector((state) => state.organizations); // const OrganisationsStore = useSelector((state) => state.organizations);
const areasStore = useSelector((state) => state.areas); const areasStore = useSelector((state) => state.areas);
const dataCenterStore = useSelector((state) => state.dataCenter); const dataCenterStore = useSelector((state) => state.dataCenter);
const [cities, setCities] = useState([]); const [cities, setCities] = useState([]);
const [districts, setDistricts] = useState([]); const [districts, setDistricts] = useState([]);
const [neighborhoods, setNeighborhoods] = useState([]); const [neighborhoods, setNeighborhoods] = useState([]);
const [organizationOptions, setOrganizationOptions] = useState([]); // const [organizationOptions, setOrganizationOptions] = useState([]);
const organizationId = localStorage.getItem("organizationId"); // const organizationId = localStorage.getItem("organizationId");
const roleTag = localStorage.getItem("roleTag"); // const roleTag = localStorage.getItem("roleTag");
const [selectedOrganization, setSelectedOrganization] = useState({ // const [selectedOrganization, setSelectedOrganization] = useState({
label: localStorage.getItem("organizationName"), // label: localStorage.getItem("organizationName"),
value: organizationId, // value: organizationId,
}); // });
const [areasOptions, setAreasOptions] = useState([]); const [areasOptions, setAreasOptions] = useState([]);
const [done, setDone] = useState(false); const [done, setDone] = useState(false);
@@ -146,7 +218,7 @@ const Map = () => {
const [showDataInputModal, setShowDataInputModal] = useState(false); const [showDataInputModal, setShowDataInputModal] = useState(false);
const [inputData, setInputData] = useState({ const [inputData, setInputData] = useState({
organization: selectedOrganization, // organization: selectedOrganization,
}); });
const [referance, setReferance] = useState( const [referance, setReferance] = useState(
Number(localStorage.getItem("referance")) || 1000 Number(localStorage.getItem("referance")) || 1000
@@ -176,15 +248,17 @@ const Map = () => {
dispatch(getDataCenters()); dispatch(getDataCenters());
}, []); }, []);
useEffect(() => { // useEffect(() => {
if (selectedOrganization?.value != "undefined") { // if (selectedOrganization?.value != "undefined") {
dispatch(getAreasWithCriteria(selectedOrganization.value)); // dispatch(getAreasWithCriteria(selectedOrganization.value));
} // }
}, [selectedOrganization]); // }, [selectedOrganization]);
useEffect(() => { useEffect(() => {
setAreasOptions([]); setAreasOptions([]);
// Load all areas without organization filter for now
// You may want to add organization filtering back later if needed
const citiesOptions = const citiesOptions =
areasStore?.areasWithCriteria areasStore?.areasWithCriteria
?.map((area) => ?.map((area) =>
@@ -235,13 +309,13 @@ const Map = () => {
]); ]);
}, [areasStore]); }, [areasStore]);
useEffect(() => { // useEffect(() => {
if (roleTag === "SUPER_ADMIN") { // if (roleTag === "SUPER_ADMIN") {
dispatch(getOrganisations()); // dispatch(getOrganisations());
} else { // } else {
dispatch(getOrganisationById(organizationId)); // dispatch(getOrganisationById(organizationId));
} // }
}, []); // }, []);
const handleDataInputButtonPressed = ({ area, type }) => { const handleDataInputButtonPressed = ({ area, type }) => {
const areaName = const areaName =
@@ -348,38 +422,38 @@ const Map = () => {
}); });
}, [selectedDistrict, districtStore?.district, year.value]); }, [selectedDistrict, districtStore?.district, year.value]);
useEffect(() => { // useEffect(() => {
let organizationOptions = []; // let organizationOptions = [];
if ( // if (
OrganisationsStore.organization && // OrganisationsStore.organization &&
OrganisationsStore.organization.length !== 0 // OrganisationsStore.organization.length !== 0
) { // ) {
organizationOptions.push({ // organizationOptions.push({
value: OrganisationsStore.organization.id, // value: OrganisationsStore.organization.id,
label: OrganisationsStore.organization.tag, // label: OrganisationsStore.organization.tag,
}); // });
if (OrganisationsStore.organization.children) { // if (OrganisationsStore.organization.children) {
organizationOptions = [ // organizationOptions = [
...organizationOptions, // ...organizationOptions,
...OrganisationsStore.organization.children.map((organization) => ({ // ...OrganisationsStore.organization.children.map((organization) => ({
value: organization.child.id, // value: organization.child.id,
label: organization.child.tag, // label: organization.child.tag,
})), // })),
]; // ];
} // }
} else { // } else {
organizationOptions = OrganisationsStore.dataOrganization.map( // organizationOptions = OrganisationsStore.dataOrganization.map(
(organization) => ({ // (organization) => ({
value: organization.id, // value: organization.id,
label: organization.tag, // label: organization.tag,
}) // })
); // );
} // }
setOrganizationOptions(organizationOptions); // setOrganizationOptions(organizationOptions);
}, [OrganisationsStore]); // }, [OrganisationsStore]);
const renderDataInputModal = () => { const renderDataInputModal = () => {
return ( return (
@@ -628,24 +702,55 @@ const Map = () => {
<Marker <Marker
key={dc.id} key={dc.id}
position={[dc.latitude, dc.longitude]} position={[dc.latitude, dc.longitude]}
icon={dataCenterIcon}
> >
<Popup> <Popup>
<div className="data-center-popup"> <div className="data-center-popup">
<h5 className="mb-2">{dc.dataCenter}</h5> <h5 className="mb-2 text-primary">{dc.dataCenter}</h5>
<p className="mb-1"><strong>{t('DataCenter.number')}:</strong> {dc.number}</p> <div className="mb-2">
<p className="mb-1"><strong>{t('DataCenter.externalId')}:</strong> {dc.externalId}</p>
<p className="mb-1"><strong>{t('DataCenter.city')}:</strong> {dc.area?.cities?.map(city => city.name).join(', ') || "-"}</p>
{dc.area && <p className="mb-1"><strong>{t('Area')}:</strong> {dc.area.tag}</p>}
{dc.projects?.length > 0 && (
<p className="mb-1"> <p className="mb-1">
<strong>{t('Projects')}:</strong> {dc.projects.length} <strong>{t("DataCenter.city")}:</strong>{" "}
<span>{dc.city?.name || "-"}</span>
</p>
{dc.address && (
<p className="mb-1 small text-muted">
<strong>{t("Address")}:</strong> {dc.address}
</p>
)}
</div>
<p className="mb-1">
<strong>{t("DataCenter.number")}:</strong> {dc.number}
</p>
<p className="mb-1">
<strong>{t("DataCenter.externalId")}:</strong>{" "}
{dc.externalId}
</p>
{dc.area && (
<p className="mb-1">
<strong>{t("Area")}:</strong> {dc.area.tag}
</p>
)}
{dc.physicalMachines?.length > 0 && (
<p className="mb-1">
<strong>{t("Physical Machines")}:</strong>{" "}
<span className="badge badge-secondary">
{dc.physicalMachines.length}
</span>
</p>
)}
{dc.dataCenterEmissionSources?.length > 0 && (
<p className="mb-1">
<strong>{t("EmissionSources.emissionSources")}:</strong>{" "}
<span className="badge badge-info">
{dc.dataCenterEmissionSources.length}
</span>
</p> </p>
)} )}
{dc.ayposURL && ( {dc.ayposURL && (
<Button <Button
className="w-100 mb-1" className="w-100 mb-1"
color="primary" color="primary"
onClick={() => window.open(dc.ayposURL, '_blank')} onClick={() => window.open(dc.ayposURL, "_blank")}
> >
Dashboard Dashboard
</Button> </Button>
@@ -699,7 +804,9 @@ const Map = () => {
setDistrictView(true); setDistrictView(true);
setZoom(8.0); setZoom(8.0);
let convertCordinates = convertCoordinates(city.coordinates); let convertCordinates = convertCoordinates(
city.coordinates
);
let length = convertCordinates[0][0][0].length; let length = convertCordinates[0][0][0].length;
let mlength = ((length + 1) / 2).toFixed(0); let mlength = ((length + 1) / 2).toFixed(0);
let lat1 = convertCordinates[0][0][0][0]; let lat1 = convertCordinates[0][0][0][0];
@@ -710,7 +817,7 @@ const Map = () => {
lat: ((lat1 + lat2) / 2).toFixed(2), lat: ((lat1 + lat2) / 2).toFixed(2),
lng: ((lng1 + lng2) / 2).toFixed(2), lng: ((lng1 + lng2) / 2).toFixed(2),
}); });
} },
}} }}
> >
<Tooltip permanent direction="center"> <Tooltip permanent direction="center">