221 Commits

Author SHA1 Message Date
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
46 changed files with 4967 additions and 3452 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

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,7 +6,7 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.4</version>
<version>2.5.5</version>
<relativePath />
</parent>
<groupId>com.sgs</groupId>

View File

@@ -121,7 +121,8 @@ public class SgsApplication implements CommandLineRunner {
@Autowired
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,
CountryService countryService, OrganizationService organizationService, UserService userService,
PasswordEncoder passwordEncoder, SectorService sectorService, SubSectorService subSectorService,
@@ -789,7 +790,7 @@ public class SgsApplication implements CommandLineRunner {
paginate_datacenters_get.setDescription(PermissionDescription.PAGINATE_DATACENTERS_GET);
permissionService.save(paginate_datacenters_get);
}
// Ensure SUPER_ADMIN has all permissions
Optional<Role> superAdminRole = roleRepo.findByTag("SUPER_ADMIN");
if (superAdminRole.isPresent()) {
@@ -858,6 +859,7 @@ public class SgsApplication implements CommandLineRunner {
}
if (cityService.findAll().isEmpty()) {
createCitiesFromJson();
createDefaultArea();
}
if (districtService.findAll().isEmpty()) {
createDistrictFromJson();
@@ -865,33 +867,30 @@ public class SgsApplication implements CommandLineRunner {
if (neighborhoodService.findAll().isEmpty()) {
createNeighborhoodsFromJson();
}
if (!cityService.findAll().isEmpty()) {
createDefaultArea();
}
}
void createDefaultArea() {
// Check if default area already exists
List<Area> existingAreas = areaService.findAll();
boolean defaultAreaExists = existingAreas.stream()
.anyMatch(area -> "Turkiye".equals(area.getTag()) && area.isDefaultArea());
.anyMatch(area -> "Turkiye".equals(area.getTag()) && area.isDefaultArea());
if (!defaultAreaExists) {
Area defaultArea = new Area();
defaultArea.setTag("Turkiye");
defaultArea.setDefaultArea(true);
defaultArea.setDeleted(false);
// Get all cities to add to the default area
List<City> allCities = cityService.findAll();
defaultArea.setCities(allCities);
// Get the Turkey country to add to the default area
List<Country> countries = countryService.findAll();
if (!countries.isEmpty()) {
defaultArea.setCountries(countries);
}
areaService.save(defaultArea);
}
}

View File

@@ -1,4 +1,5 @@
package com.sgs.graphql.dataCenter.domain;
import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonManagedReference;
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.Fetch;
import org.hibernate.annotations.FetchMode;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
@@ -27,7 +27,7 @@ public class DataCenter extends BaseDomain {
@Column(unique = true)
private Integer externalId;
private Integer number;
private Area area;
private City city;
@@ -39,16 +39,14 @@ public class DataCenter extends BaseDomain {
private EmissionScope emissionScope;
private Double consuptionAmount;
private ActivitySubUnit activitySubUnit;
// New attributes
private String ayposURL;
private String address;
private Double latitude;
private Double longitude;
@Column(name = "data_center_name")
@Transactional
public String getDataCenter() {
return dataCenter;
}
@@ -96,7 +94,6 @@ public class DataCenter extends BaseDomain {
this.number = number;
}
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "sector_id")
public Sector getSector() {

View File

@@ -17,10 +17,10 @@ public class DataCenterDto {
private Integer externalId;
private Integer number;
private AreaDto area;
@JsonProperty("physical_machines")
private Map<String, PhysicalMachineDto> physicalMachine;
// Emission calculation fields
private SectorDto sector;
private SubSectorDto subSector;
@@ -62,12 +62,12 @@ public class DataCenterDto {
this.number = number;
}
public AreaDto getArea() {
return area;
public AreaDto getArea() {
return area;
}
public void setArea(AreaDto area) {
this.area = area;
public void setArea(AreaDto area) {
this.area = area;
}
public Map<String, PhysicalMachineDto> getPhysicalMachine() {

View File

@@ -1,18 +1,26 @@
package com.sgs.graphql.dataCenter.mutation;
import com.sgs.exception.GraphQLCustomException;
import com.sgs.graphql.dataCenter.mutation.mapper.DataCenterMapper;
import com.sgs.graphql.dataCenter.service.DataCenterService;
import com.sgs.graphql.dataCenter.domain.DataCenter;
import com.sgs.graphql.dataCenter.mutation.input.DataCenterCreateInput;
import com.sgs.graphql.dataCenter.mutation.input.DataCenterUpdateInput;
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.schema.DataFetchingEnvironment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;
import javax.transaction.Transactional;
import javax.validation.Valid;
import java.util.NoSuchElementException;
import java.util.UUID;
@Validated
@@ -21,57 +29,128 @@ public class DataCenterMutation implements GraphQLMutationResolver {
private final DataCenterService dataCenterService;
private final DataCenterMapper dataCenterMapper;
private final SystemLogger systemLogger;
private final UserLogger userLogger;
private final UserNotificationMutation notificationMutation;
@Autowired
public DataCenterMutation(DataCenterService dataCenterService, DataCenterMapper dataCenterMapper) {
public DataCenterMutation(DataCenterService dataCenterService, DataCenterMapper dataCenterMapper,
SystemLogger systemLogger, UserLogger userLogger,
UserNotificationMutation notificationMutation) {
this.dataCenterService = dataCenterService;
this.dataCenterMapper = dataCenterMapper;
this.systemLogger = systemLogger;
this.userLogger = userLogger;
this.notificationMutation = notificationMutation;
}
@PreAuthorize("hasAuthority('" + PermissionName.DATA_CENTER_CREATE + "')")
public DataCenter createDataCenter(@Valid DataCenterCreateInput input) {
// Check for duplicate externalId
if (input.getExternalId() != null && dataCenterService.existsByExternalId(input.getExternalId())) {
throw new RuntimeException("This external id already exists: " + input.getExternalId());
@Transactional
public DataCenter createDataCenter(@Valid DataCenterCreateInput input, DataFetchingEnvironment environment) {
try {
// 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 + "')")
public DataCenter updateDataCenter(UUID id, @Valid DataCenterUpdateInput input) {
return dataCenterService.findById(id)
.map(dataCenter -> {
// Check for duplicate externalId if it's being updated
if (input.getExternalId() != null &&
!input.getExternalId().equals(dataCenter.getExternalId()) &&
dataCenterService.existsByExternalId(input.getExternalId())) {
throw new RuntimeException("This external id already exists: " + input.getExternalId());
}
return dataCenterService.update(dataCenterMapper.updateEntity(dataCenter, input));
})
.orElseThrow(() -> new RuntimeException("Data center not found with ID: " + id));
@Transactional
public DataCenter updateDataCenter(UUID id, @Valid DataCenterUpdateInput input,
DataFetchingEnvironment environment) {
try {
DataCenter dataCenter = dataCenterService.findById(id)
.orElseThrow(() -> new NoSuchElementException("Data center not found with ID: " + id));
// Check for duplicate externalId if it's being updated
if (input.getExternalId() != null &&
!input.getExternalId().equals(dataCenter.getExternalId()) &&
dataCenterService.existsByExternalId(input.getExternalId())) {
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 + "')")
public Boolean deleteDataCenter(UUID id) {
@Transactional
public String deleteDataCenter(UUID id, DataFetchingEnvironment environment) {
String dataCenterName = "";
try {
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);
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) {
System.out.println("DataCenter deletion error: " + e.getMessage());
return false;
systemLogger.createSystemLog(LogType.ERROR, "Veri merkezi silinirken hata oluştu: " + e.getMessage());
return "false";
}
}
}

View File

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

View File

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

View File

@@ -50,13 +50,13 @@ public class DataCenterMapper extends BaseCreateUpdateMapper<DataCenter, DataCen
@Override
public DataCenter toEntity(DataCenterCreateInput input) {
DataCenter entity = new DataCenter();
// Basic fields
entity.setDataCenter(input.getDataCenter());
entity.setExternalId(input.getExternalId());
entity.setNumber(input.getNumber());
entity.setConsuptionAmount(input.getConsuptionAmount());
// Convert ID references to entities
if (input.getAreaId() != null) {
entity.setArea(areaService.findById(input.getAreaId()).orElse(null));
@@ -68,53 +68,56 @@ public class DataCenterMapper extends BaseCreateUpdateMapper<DataCenter, DataCen
if (input.getSectorId() != null) {
entity.setSector(sectorService.findById(input.getSectorId()).orElse(null));
}
if (input.getSubSectorId() != null) {
entity.setSubSector(subSectorService.findById(input.getSubSectorId()).orElse(null));
}
if (input.getEmissionScopeId() != null) {
entity.setEmissionScope(emissionScopeService.findById(input.getEmissionScopeId()).orElse(null));
}
if (input.getActivitySubUnitId() != null) {
entity.setActivitySubUnit(activitySubUnitService.findById(input.getActivitySubUnitId()).orElse(null));
}
// New attributes
entity.setAyposURL(input.getAyposURL());
entity.setAddress(input.getAddress());
entity.setLatitude(input.getLatitude());
entity.setLongitude(input.getLongitude());
// Handle multiple emission sources if provided
if (input.getDataCenterEmissionSources() != null && !input.getDataCenterEmissionSources().isEmpty()) {
List<DataCenterEmissionSource> dataCenterEmissionSources = new ArrayList<>();
for (DataCenterEmissionSourceInput emissionSourceInput : input.getDataCenterEmissionSources()) {
DataCenterEmissionSource dcEmissionSource = new DataCenterEmissionSource();
dcEmissionSource.setDataCenter(entity);
// Set EmissionSource
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
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
dcEmissionSource.setIsDefault(emissionSourceInput.getIsDefault() != null ? emissionSourceInput.getIsDefault() : false);
dcEmissionSource.setIsDefault(
emissionSourceInput.getIsDefault() != null ? emissionSourceInput.getIsDefault() : false);
dcEmissionSource.setPercentage(emissionSourceInput.getPercentage());
dataCenterEmissionSources.add(dcEmissionSource);
}
entity.setDataCenterEmissionSources(dataCenterEmissionSources);
}
return entity;
}
@@ -124,19 +127,19 @@ public class DataCenterMapper extends BaseCreateUpdateMapper<DataCenter, DataCen
if (input.getDataCenter() != null) {
entity.setDataCenter(input.getDataCenter());
}
if (input.getExternalId() != null) {
entity.setExternalId(input.getExternalId());
}
if (input.getNumber() != null) {
entity.setNumber(input.getNumber());
}
if (input.getConsuptionAmount() != null) {
entity.setConsuptionAmount(input.getConsuptionAmount());
}
// Update relationships only if provided
if (input.getAreaId() != null) {
entity.setArea(areaService.findById(input.getAreaId()).orElse(null));
@@ -148,62 +151,65 @@ public class DataCenterMapper extends BaseCreateUpdateMapper<DataCenter, DataCen
if (input.getSectorId() != null) {
entity.setSector(sectorService.findById(input.getSectorId()).orElse(null));
}
if (input.getSubSectorId() != null) {
entity.setSubSector(subSectorService.findById(input.getSubSectorId()).orElse(null));
}
if (input.getEmissionScopeId() != null) {
entity.setEmissionScope(emissionScopeService.findById(input.getEmissionScopeId()).orElse(null));
}
if (input.getActivitySubUnitId() != null) {
entity.setActivitySubUnit(activitySubUnitService.findById(input.getActivitySubUnitId()).orElse(null));
}
// Handle multiple emission sources update if provided
if (input.getDataCenterEmissionSources() != null) {
// Clear existing emission sources and add new ones
// Clear existing emission sources from the managed collection
entity.getDataCenterEmissionSources().clear();
List<DataCenterEmissionSource> dataCenterEmissionSources = new ArrayList<>();
// Add new emission sources to the same managed collection
for (DataCenterEmissionSourceInput emissionSourceInput : input.getDataCenterEmissionSources()) {
DataCenterEmissionSource dcEmissionSource = new DataCenterEmissionSource();
dcEmissionSource.setDataCenter(entity);
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) {
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());
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)
if (input.getAyposURL() != null) {
entity.setAyposURL(input.getAyposURL());
}
if (input.getAddress() != null) {
entity.setAddress(input.getAddress());
}
if (input.getLatitude() != null) {
entity.setLatitude(input.getLatitude());
}
if (input.getLongitude() != null) {
entity.setLongitude(input.getLongitude());
}
return entity;
}
}

View File

@@ -11,17 +11,16 @@ import javax.transaction.Transactional;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.security.access.prepost.PreAuthorize;
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.PhysicalMachine;
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.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.sort.SortBy;
@@ -30,48 +29,46 @@ import graphql.kickstart.tools.GraphQLQueryResolver;
@Component
public class DataCenterQueryResolver implements GraphQLQueryResolver {
private final DataCenterService DataCenterService;
private final DataCenterRepo dataCenterRepo;
private final PhysicalMachineRepo physicalMachineRepo;
private final AuthorizationService authorizationService;
private final SystemLogger systemLogger;
private final DataCenterService dataCenterService;
private final PhysicalMachineService physicalMachineService;
@Autowired
public DataCenterQueryResolver(AuthorizationService authorizationService, SystemLogger systemLogger, DataCenterService DataCenterService, DataCenterRepo dataCenterRepo, PhysicalMachineRepo physicalMachineRepo) {
this.DataCenterService = DataCenterService;
this.dataCenterRepo = dataCenterRepo;
this.physicalMachineRepo = physicalMachineRepo;
this.authorizationService = authorizationService;
this.systemLogger = systemLogger;
public DataCenterQueryResolver(DataCenterService dataCenterService, PhysicalMachineService physicalMachineService) {
this.dataCenterService = dataCenterService;
this.physicalMachineService = physicalMachineService;
}
@PreAuthorize("hasAuthority('" + PermissionName.DATA_CENTER_READ + "')")
public DataCenter dataCenter(UUID id) {
return DataCenterService.findById(id).orElse(null);
return dataCenterService.findById(id).orElse(null);
}
@Transactional
@PreAuthorize("hasAuthority('" + PermissionName.DATA_CENTER_READ + "')")
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>())
.stream()
.map(SortBy::toOrder)
.collect(Collectors.toList())));
return dataCenters;
}
public DataCenterPageable paginateDataCenters(Pagination pagination, DataCenterCriteria criteria, List<SortBy> sortBy) {
return new DataCenterPageable(DataCenterService.filterWithPaginate(ObjectUtils.defaultIfNull(criteria, new DataCenterCriteria()),
Pagination.toPageRequest(pagination, sortBy)));
@PreAuthorize("hasAuthority('" + PermissionName.PAGINATE_DATACENTERS_GET + "')")
public DataCenterPageable paginateDataCenters(Pagination pagination, DataCenterCriteria criteria,
List<SortBy> sortBy) {
return new DataCenterPageable(
dataCenterService.filterWithPaginate(ObjectUtils.defaultIfNull(criteria, new DataCenterCriteria()),
Pagination.toPageRequest(pagination, sortBy)));
}
public Optional<DataCenter> getByNumber(Integer id) {
return dataCenterRepo.findByNumber(id).stream().findFirst();
@PreAuthorize("hasAuthority('" + PermissionName.DATA_CENTER_READ + "')")
public Optional<DataCenter> getByNumber(Integer number) {
return dataCenterService.findByNumber(number);
}
@PreAuthorize("hasAuthority('" + PermissionName.DATA_CENTER_READ + "')")
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.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.repository.query.Param;
import org.springframework.stereotype.Repository;
@@ -11,14 +12,14 @@ import java.util.List;
import java.util.Optional;
@Repository
public interface DataCenterEmissionSourceRepo extends JpaRepository<DataCenterEmissionSource, String> {
public interface DataCenterEmissionSourceRepo extends BaseRepo<DataCenterEmissionSource> {
List<DataCenterEmissionSource> findByDataCenter(DataCenter dataCenter);
Optional<DataCenterEmissionSource> findByDataCenterAndIsDefaultTrue(DataCenter dataCenter);
@Query("SELECT dces FROM DataCenterEmissionSource dces WHERE dces.dataCenter.id = :dataCenterId")
List<DataCenterEmissionSource> findByDataCenterId(@Param("dataCenterId") String dataCenterId);
void deleteByDataCenter(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,15 +8,26 @@ import com.sgs.lib.dao.service.BaseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Optional;
@Service
public class DataCenterService extends BaseService<DataCenter, DataCenterRepo, DataCenterCriteria, DataCenterCriteriaSpec> {
public class DataCenterService
extends BaseService<DataCenter, DataCenterRepo, DataCenterCriteria, DataCenterCriteriaSpec> {
@Autowired
public DataCenterService(DataCenterRepo repository, DataCenterCriteriaSpec criteriaSpec) {
super(repository, criteriaSpec);
}
public boolean existsByExternalId(Integer 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;
@Service
public class MainDataTableService extends BaseService<MainDataTable, MainDataTableRepo, MainDataTableCriteria, MainDataTableCriteriaSpec> {
public class MainDataTableService
extends BaseService<MainDataTable, MainDataTableRepo, MainDataTableCriteria, MainDataTableCriteriaSpec> {
@PersistenceContext
private EntityManager entityManager;
@@ -35,10 +36,10 @@ public class MainDataTableService extends BaseService<MainDataTable, MainDataTab
public List<VMEmissionSummary> getVMEmissionSummaries() {
return getVMEmissionSummaries(null);
}
public List<VMEmissionSummary> getVMEmissionSummaries(UUID datacenterId) {
List<String> whereConditions = new ArrayList<>();
if (datacenterId != null) {
whereConditions.add("dc.id = decode(replace(:datacenterId, '-', ''), 'hex')");
}
@@ -69,7 +70,7 @@ public class MainDataTableService extends BaseService<MainDataTable, MainDataTab
""";
Query query = entityManager.createNativeQuery(sql);
// Add parameters if provided
if (datacenterId != null) {
query.setParameter("datacenterId", datacenterId.toString());
@@ -77,41 +78,42 @@ public class MainDataTableService extends BaseService<MainDataTable, MainDataTab
@SuppressWarnings("unchecked")
List<Object[]> results = query.getResultList();
return results.stream().map(row -> {
VMEmissionSummary summary = new VMEmissionSummary();
// Handle UUID conversion from hex format
String uuidStr = (String) row[0];
UUID vmId = convertHexToUUID(uuidStr);
summary.setVmId(vmId);
summary.setVmName((String) row[1]);
summary.setVmPower((Double) row[2]);
summary.setVmStatus((String) row[3]);
summary.setTotalEmission((Double) row[4]);
// Convert Timestamp to LocalDateTime for created_date
Timestamp timestamp = (Timestamp) row[5];
if (timestamp != null) {
summary.setCreatedDate(timestamp.toLocalDateTime());
}
summary.setPhysicalMachine((String) row[6]);
summary.setCloudSystem((String) row[7]);
summary.setDataCenter((String) row[8]);
// Individual emission values
summary.setCo2((Double) row[9]);
summary.setCh4((Double) row[10]);
summary.setN2o((Double) row[11]);
return summary;
}).collect(Collectors.toList());
}
/**
* Converts PostgreSQL hex format UUID to proper UUID format
*
* @param hexUuid UUID in hex format (e.g., \x6205c18b8d1e4f0fa5154212fb44050b)
* @return UUID object
*/
@@ -121,11 +123,11 @@ public class MainDataTableService extends BaseService<MainDataTable, MainDataTab
String hex = hexUuid.substring(2);
// Insert hyphens to make it a proper UUID format
// UUID format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
String formatted = hex.substring(0, 8) + "-" +
hex.substring(8, 12) + "-" +
hex.substring(12, 16) + "-" +
hex.substring(16, 20) + "-" +
hex.substring(20);
String formatted = hex.substring(0, 8) + "-" +
hex.substring(8, 12) + "-" +
hex.substring(12, 16) + "-" +
hex.substring(16, 20) + "-" +
hex.substring(20);
return UUID.fromString(formatted);
} else {
// If it's already in proper format, parse directly

View File

@@ -838,8 +838,8 @@ public class MessageListener {
input.setVmId(vm.getId());
System.out.println("🔍 Setting VM ID: " + vm.getId());
// Use the source-specific power consumption (percentage of total VM power)
// Format to 6 decimal places to avoid very long strings
// Use the source-specific power consumption (percentage of total VM power)
// Format to 6 decimal places to avoid very long strings
String formattedPower = String.format("%.6f", sourceSpecificPower);
input.setConsuptionAmount(formattedPower);
System.out.println("🔍 Setting Consumption Amount: " + formattedPower + "W");
@@ -849,7 +849,8 @@ public class MessageListener {
System.out.println(" Year: " + (input.getYear() != null ? input.getYear().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("🔍 VM Emission Input for Source:");
System.out.println(" VM ID: " + vm.getId());
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
# 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.host=188.132.198.145
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.rabbitmq.username=testuser
spring.rabbitmq.password=JGasF24561AZv2894De
spring.rabbitmq.virtual-host=/
spring.rabbitmq.connection-timeout=20000
spring.rabbitmq.template.retry.enabled=true
@@ -34,3 +28,6 @@ spring.rabbitmq.template.retry.max-attempts=3
spring.rabbitmq.template.retry.initial-interval=1000ms
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

@@ -1,104 +1,108 @@
# SGE System Frontend
## Overview
The frontend of the SGE System is a modern web application built with **React**, providing an interactive and user-friendly interface. It communicates with the backend API to deliver a seamless experience for users.
## Technology Stack
- **React** UI library
- **React Router** Routing
- **i18n** Internationalization
- **Docker** Containerization
## Repository Structure
```
SGE/
├── sge-backend/ # Backend source code
├── sge-frontend/ # Frontend source code
├── config.conf # Centralized configuration file (see below)
├── docker-compose.yml # Docker Compose file (see below)
```
## Setup and Installation
### Prerequisites
- **Node.js** (v14.0.0 required) and npm
- **Docker** (for containerized deployment)
#### Node.js Version Management
If you need to switch Node versions, use nvm:
```sh
nvm install v14.0.0
nvm use v14.0.0
unset NODE_OPTIONS
```
### Frontend Setup
#### Local Development
1. Clone the repository and navigate to the frontend directory:
```sh
git clone <repository-url>
cd SGE/sge-frontend
```
2. Ensure `config.conf` is in the project root (`SGE/`).
You can either:
- Manually set environment variables from `config.conf`
- Or configure your IDE to load variables from `config.conf`
3. Install dependencies:
```sh
npm install
```
4. Start the development server:
```sh
npm start
```
#### Docker Deployment
1. Ensure both `config.conf` and `docker-compose.yml` are in the project root (`SGE/`).
2. From the root directory, build and run the frontend (and backend) using Docker:
```sh
docker-compose up --build
```
## Configuration Management
The SGE System uses a centralized `config.conf` file for all environment variables.
**Location:** Place `config.conf` in the root directory of your project, alongside `docker-compose.yml`.
This file contains environment variables for both backend and frontend components, including:
- API connection settings
- Mail configuration
- Application URLs
When running with Docker, environment variables are automatically loaded from `config.conf` via the `env_file` directive in `docker-compose.yml`.
For local development, you can either:
- Use the same `config.conf` file and manually set the environment variables
- Configure your IDE to load these variables from the file
Refer to the backend README for more details on configuration options and structure.
## Integration with Backend
The frontend expects the backend API to be available at the host and port specified in `config.conf` (`API_PROTOCOL`, `API_HOST`, `SERVER_PORT`).
Ensure both services are configured consistently.
## License
[Insert your license information here]
# SGE System Frontend
## Overview
The frontend of the SGE System is a modern web application built with **React**, providing an interactive and user-friendly interface. It communicates with the backend API to deliver a seamless experience for users.
## Technology Stack
- **React** UI library
- **React Router** Routing
- **i18n** Internationalization
- **Docker** Containerization
## Repository Structure
```
SGE/
├── sge-backend/ # Backend source code
├── sge-frontend/ # Frontend source code
├── config.conf # Centralized configuration file (see below)
├── docker-compose.yml # Docker Compose file (see below)
```
## Setup and Installation
### Prerequisites
- **Node.js** (v14.0.0 required) and npm
- **Docker** (for containerized deployment)
#### Node.js Version Management
If you need to switch Node versions, use nvm:
```sh
nvm install v14.0.0
nvm use v14.0.0
unset NODE_OPTIONS
```
### Frontend Setup
#### Local Development
1. Clone the repository and navigate to the frontend directory:
```sh
git clone <repository-url>
cd SGE/sge-frontend
```
2. Ensure `config.conf` is in the project root (`SGE/`).
You can either:
- Manually set environment variables from `config.conf`
- Or configure your IDE to load variables from `config.conf`
3. Install dependencies:
```sh
npm install
```
4. Start the development server:
```sh
npm start
```
#### Docker Deployment
1. Ensure both `config.conf` and `docker-compose.yml` are in the project root (`SGE/`).
2. From the root directory, build and run the frontend (and backend) using Docker:
```sh
docker-compose up --build
```
## Configuration Management
The SGE System uses a centralized `config.conf` file for all environment variables.
**Location:** Place `config.conf` in the root directory of your project, alongside `docker-compose.yml`.
This file contains environment variables for both backend and frontend components, including:
- API connection settings
- Mail configuration
- Application URLs
When running with Docker, environment variables are automatically loaded from `config.conf` via the `env_file` directive in `docker-compose.yml`.
For local development, you can either:
- Use the same `config.conf` file and manually set the environment variables
- Configure your IDE to load these variables from the file
Refer to the backend README for more details on configuration options and structure.
## Integration with Backend
The frontend expects the backend API to be available at the host and port specified in `config.conf` (`API_PROTOCOL`, `API_HOST`, `SERVER_PORT`).
Ensure both services are configured consistently.
## License
[Insert your license information here]
## CI/CD Testing v20

View File

@@ -1,39 +1,32 @@
server {
listen 80;
server_name bgreen.blc-css.com;
root /usr/share/nginx/html;
index index.html index.htm;
location / {
try_files $uri /index.html;
}
location /api/v1/graphql {
proxy_pass http://bgreen-backend:8080/api/v1/graphql;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /api/v1/upload {
proxy_pass http://bgreen-backend:8080/upload;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# location /api/v1/datacenter {
# proxy_pass http://backend:8080/api/v1/datacenter;
# proxy_set_header Host $host;
# proxy_set_header X-Real-IP $remote_addr;
# }
# Hata durumlarında da index.html'i sun
error_page 404 /index.html;
gzip on;
gzip_vary on;
gzip_min_length 10240;
gzip_proxied any;
gzip_types text/plain text/css text/xml text/javascript application/javascript application/json application/xml application/rss+xml application/atom+xml image/svg+xml;
gzip_comp_level 5;
}
}

View File

@@ -1,131 +1,131 @@
{
"name": "sgs-web",
"version": "1.0.0",
"private": true,
"dependencies": {
"@apollo/client": "^3.13.8",
"@casl/react": "4.0.0",
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.10.6",
"@mui/icons-material": "^5.2.4",
"@mui/material": "^5.2.4",
"animate.css": "4.1.1",
"axios": "^0.21.1",
"bootstrap": "4.5.2",
"chart.js": "^4.3.0",
"chartjs-plugin-datalabels": "^2.2.0",
"classnames": "2.2.6",
"dotenv": "^14.3.2",
"file-saver": "^2.0.5",
"graphql": "^16.11.0",
"html2canvas": "^1.4.1",
"i18next": "^22.4.14",
"i18next-browser-languagedetector": "^7.0.1",
"i18next-http-backend": "^2.2.0",
"jquery": "^3.7.1",
"jspdf": "^2.5.1",
"jwt-decode": "^3.1.2",
"leaflet": "^1.6.0",
"material-react-table": "^1.14.0",
"moment": "2.29.1",
"notistack": "^2.0.8",
"postcss-rtl": "1.5.0",
"prop-types": "15.7.2",
"react": "17.0.1",
"react-bootstrap": "^2.10.6",
"react-chartjs-2": "^5.2.0",
"react-color": "^2.19.3",
"react-data-table-component": "^7.5.0",
"react-datepicker": "^4.16.0",
"react-dom": "17.0.1",
"react-feather": "~2.0.3",
"react-i18next": "^12.2.0",
"react-intl": "6.0.5",
"react-leaflet": "^3.2.5",
"react-paginate": "8.2.0",
"react-perfect-scrollbar": "^1.5.5",
"react-redux": "7.2.2",
"react-router-dom": "^5.2.0",
"react-scroll-up": "1.3.7",
"react-select": "4.0.2",
"react-toastify": "^7.0.3",
"reactstrap": "9.2.3",
"redux": "4.0.5",
"redux-debounced": "0.5.0",
"redux-thunk": "2.3.0",
"styled-components": "^5.3.6",
"sweetalert2": "11.0.0",
"sweetalert2-react-content": "4.2.0",
"swiper": "6.0.4",
"uuid": "^9.0.0",
"web-vitals": "^1.0.1",
"websocket": "^1.0.34",
"wnumb": "1.2.0",
"xlsx": "^0.18.5",
"yarn": "1.21.1",
"yup": "0.32.8"
},
"scripts": {
"start": "react-app-rewired start",
"build:dev": "react-app-rewired build --mode development",
"build:prod": "react-app-rewired build --mode production",
"build": "react-app-rewired build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"lint": "eslint src/**/*.js src/**/*.jsx",
"lint:fix": "eslint src/**/*.js --fix"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"@babel/core": "^7.27.1",
"@babel/plugin-proposal-class-properties": "^7.18.6",
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
"@babel/preset-env": "^7.27.1",
"@babel/preset-react": "^7.27.1",
"@craco/craco": "^7.1.0",
"@swc/core": "^1.11.24",
"@types/leaflet": "^1.7.5",
"@types/sortablejs": "^1.10.6",
"babel-eslint": "^10.1.0",
"babel-loader": "^10.0.0",
"babel-plugin-styled-components": "^2.1.4",
"core-js": "^3.42.0",
"eslint": "^8.48.0",
"eslint-config-react-app": "^7.0.1",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-jsx-a11y": "^6.7.1",
"eslint-plugin-react": "^7.33.0",
"eslint-plugin-react-hooks": "^4.6.0",
"react-app-rewire-postcss": "^3.0.2",
"react-app-rewired": "^2.2.1",
"react-error-overlay": "^6.0.9",
"react-loadable": "^5.5.0",
"react-scripts": "^5.0.1",
"sass": "^1.81.0",
"sass-loader": "^8.0.2",
"swc-loader": "^0.2.6",
"typescript": "^4.9.5",
"webpack": "^5.96.1"
},
"resolutions": {
"react-error-overlay": "6.0.9"
},
"homepage": ""
}
{
"name": "sgs-web",
"version": "1.0.3",
"private": true,
"dependencies": {
"@apollo/client": "^3.13.8",
"@casl/react": "4.0.0",
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.10.6",
"@mui/icons-material": "^5.2.4",
"@mui/material": "^5.2.4",
"animate.css": "4.1.1",
"axios": "^0.21.1",
"bootstrap": "4.5.2",
"chart.js": "^4.3.0",
"chartjs-plugin-datalabels": "^2.2.0",
"classnames": "2.2.6",
"dotenv": "^14.3.2",
"file-saver": "^2.0.5",
"graphql": "^16.11.0",
"html2canvas": "^1.4.1",
"i18next": "^22.4.14",
"i18next-browser-languagedetector": "^7.0.1",
"i18next-http-backend": "^2.2.0",
"jquery": "^3.7.1",
"jspdf": "^2.5.1",
"jwt-decode": "^3.1.2",
"leaflet": "^1.6.0",
"material-react-table": "^1.14.0",
"moment": "2.29.1",
"notistack": "^2.0.8",
"postcss-rtl": "1.5.0",
"prop-types": "15.7.2",
"react": "17.0.1",
"react-bootstrap": "^2.10.6",
"react-chartjs-2": "^5.2.0",
"react-color": "^2.19.3",
"react-data-table-component": "^7.5.0",
"react-datepicker": "^4.16.0",
"react-dom": "17.0.1",
"react-feather": "~2.0.3",
"react-i18next": "^12.2.0",
"react-intl": "6.0.5",
"react-leaflet": "^3.2.5",
"react-paginate": "8.2.0",
"react-perfect-scrollbar": "^1.5.5",
"react-redux": "7.2.2",
"react-router-dom": "^5.2.0",
"react-scroll-up": "1.3.7",
"react-select": "4.0.2",
"react-toastify": "^7.0.3",
"reactstrap": "9.2.3",
"redux": "4.0.5",
"redux-debounced": "0.5.0",
"redux-thunk": "2.3.0",
"styled-components": "^5.3.6",
"sweetalert2": "11.0.0",
"sweetalert2-react-content": "4.2.0",
"swiper": "6.0.4",
"uuid": "^9.0.0",
"web-vitals": "^1.0.1",
"websocket": "^1.0.34",
"wnumb": "1.2.0",
"xlsx": "^0.18.5",
"yarn": "1.21.1",
"yup": "0.32.8"
},
"scripts": {
"start": "react-app-rewired start",
"build:dev": "react-app-rewired build --mode development",
"build:prod": "react-app-rewired build --mode production",
"build": "react-app-rewired build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"lint": "eslint src/**/*.js src/**/*.jsx",
"lint:fix": "eslint src/**/*.js --fix"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"@babel/core": "^7.27.1",
"@babel/plugin-proposal-class-properties": "^7.18.6",
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
"@babel/preset-env": "^7.27.1",
"@babel/preset-react": "^7.27.1",
"@craco/craco": "^7.1.0",
"@swc/core": "^1.11.24",
"@types/leaflet": "^1.7.5",
"@types/sortablejs": "^1.10.6",
"babel-eslint": "^10.1.0",
"babel-loader": "^10.0.0",
"babel-plugin-styled-components": "^2.1.4",
"core-js": "^3.42.0",
"eslint": "^8.48.0",
"eslint-config-react-app": "^7.0.1",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-jsx-a11y": "^6.7.1",
"eslint-plugin-react": "^7.33.0",
"eslint-plugin-react-hooks": "^4.6.0",
"react-app-rewire-postcss": "^3.0.2",
"react-app-rewired": "^2.2.1",
"react-error-overlay": "^6.0.9",
"react-loadable": "^5.5.0",
"react-scripts": "^5.0.1",
"sass": "^1.81.0",
"sass-loader": "^8.0.2",
"swc-loader": "^0.2.6",
"typescript": "^4.9.5",
"webpack": "^5.96.1"
},
"resolutions": {
"react-error-overlay": "6.0.9"
},
"homepage": ""
}

View File

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

View File

@@ -1,311 +1,315 @@
{
"Actions": "Aksiyonlar",
"Active": "Aktif",
"ByName": "İsme Göre",
"CreatedTime": "Oluşturulma Zamanı",
"Description": " Açıklaması",
"Filter": "Filtrele",
"Management": "Yönetim",
"Passive": "Pasif",
"Show": "Göster",
"Status": "Durum",
"Time": "Zaman ",
"Activities": {
"activity": "Aktivite ",
"activities": "Aktiviteler ",
"type": "Log Tipi",
"message": "Log Mesajı"
},
"Areas": {
"addArea": "Alan Ekle",
"area": "Alan ",
"areas": "Alanlar ",
"areaName": "Alan Adı ",
"city": "Şehir ",
"cities": "Şehirler ",
"cityName": "Şehir Adı ",
"country": "Ülke ",
"countries": "Ülkeler ",
"countryName": "Ülke Adı ",
"countryCode": "Ülke Kodu ",
"district": "İlçe ",
"districts": "İlçeler",
"districtName": "İlçe Adı",
"neighborhood": "Mahalle ",
"neighborhoods": "Mahalleler ",
"neighborhoodName": "Mahalle Adı",
"addNeighborhood": "Mahalle Ekle",
"latitude": "Enlem",
"longitude": "Boylam"
},
"Auth": {
"authorized": "Devam etmek için yetkilendirilmiş kullanıcı bilgilerinizi giriniz.",
"didUForgotPassword": "Şifrenizi mi unuttunuz?",
"logout": ıkış Yap",
"logoutMessage": " Çıkış yaptınız. Yönlendiriliyorsunuz...",
"login": "Giriş Yap",
"loginMessage": " Giriş başarılı yönlendiriliyorsunuz...",
"password": "Şifre ",
"welcome": "Hoşgeldiniz",
"incorrectForm": "Kullanıcı bilgileri hatalıdır. Lütfen tekrar deneyiniz."
},
"Cruds": {
"add": " Ekle",
"cancel": " İptal",
"delete": "Sil",
"edit": "Düzenle",
"reactive": "Aktif Et",
"save": "Kaydet",
"saving": "Kaydediliyor..",
"update": "Güncelle"
},
"Common": {
"save": "Kaydet",
"cancel": " İptal"
},
"DataInput": {
"area": "Bölge ",
"report": "Rapor ",
"reports": "Raw Data",
"data": "Veri ",
"datas": "Veriler ",
"dataInput": "Veri Girişi",
"year": "Yıl",
"month": "Ay",
"consumptionAmount": "Tüketim Miktarı",
"consumptionUnit": "Tüketim Birimi",
"gpcReference": "GPC Referans",
"total": "Toplam ",
"save": "Veriyi Kaydet",
"update": "Veriyi Güncelle",
"showDeleted": "Silinen Raporları Göster",
"result": "Sonuç",
"directToAllDatas": "Tüm Verileri Gör",
"addNewData": "Yeni Veri Ekle",
"failUploadExcel": "Dosya yüklenirken hata oluştu!"
},
"Graphics": {
"graphics": "Raporlar",
"reports": "Raporlar"
},
"EmissionSources": {
"dataSet": "Veri Seti",
"emissionSource": "Emisyon Kaynağı ",
"emissionSources": "Emisyon Kaynakları ",
"emissionSourceName": "Emisyon Kaynağı Adı",
"addEmissionSource": "Emisyon Kaynağı Ekle",
"existingEmissionName": "Bu isimde bir emisyon kaynağı mevcuttur!",
"sector": "Veri Sektörü ",
"sectors": "Veri Sektörleri ",
"subSector": "Sektör Alt Birimi ",
"subSectors": "Sektör Alt Birimleri ",
"subUnit": "Faaliyet Alt Birimi ",
"subUnits": "Faaliyet Alt Birimleri ",
"emissionScopes": "Emisyon Kapsamı ",
"emissionFactors": "Emisyon Faktörleri ",
"showDeletedEmissionSource": "Silinen Emisyon Kaynaklarını Göster"
},
"Map": {
"map": "Harita",
"goBack": "Geri dön",
"reference": "Referans",
"title": "Harita"
},
"Months": {
"1": "Ocak",
"2": "Şubat",
"3": "Mart",
"4": "Nisan",
"5": "Mayıs",
"6": "Haziran",
"7": "Temmuz",
"8": "Ağustos",
"9": "Eylül",
"10": "Ekim",
"11": "Kasım",
"12": "Aralık",
"null": "Yıl Geneli",
"0": "Yıl Geneli"
},
"Notifications": {
"content": "İçerik ",
"notification": "Bildirim ",
"notifications": "Bildirimler ",
"showAll": "Tüm Bildirimleri Göster",
"title": "Başlık ",
"notificationType": "Bildirim Tipi "
},
"Organizations": {
"organization": "Organizasyon ",
"organizations": "Organizasyonlar",
"organizationName": "Organizasyon Adı",
"parentOrganization": "Bağlı Olduğu Organizasyon",
"childOrganization": "Alt Organizasyonu",
"addOrganization": "Organizasyon Ekle",
"existingName": "Bu isimde bir organizasyon mevcuttur!.",
"showDeletedOrganizations": "Silinen Organizasyonları Göster"
},
"PasswordLabel": {
"passwordLabel": "Şifre",
"confirmPassword": "Şifre Tekrar",
"oldPassword": "Eski Şifre",
"newPassword": "Yeni Şifre",
"newConfirmPassword": "Yeni Şifre Tekrar",
"verificationCode": "Doğrulama Kodu",
"cannotbeleftblank": " Boş Bırakılamaz ",
"passwordNotSame": "Şifreler aynı değil",
"passwordValidation": "Şifre 6-20 karakter uzunluğunda, en az 1 sayı, 1 büyük harf ve 1 küçük harf içermelidir!",
"forgotPassword": "Şifremi Unuttum",
"enterEmail": "Geçerli bir email giriniz.",
"send": "Gönder",
"redirectToReset": "Şifre sıfırlama ekranına yönlendiriliyorsunuz..",
"resetPassword": "Şifre Sıfırlama",
"resend": "Doğrulama Kodunu Tekrar Gönder",
"invalidVerificationCode": "Geçersiz doğrulama kodu!",
"redirectToLogin": "Giriş ekranına yönlendiriliyorsunuz.."
},
"Roles": {
"role": "Rol ",
"roles": "Roller",
"roleName": "Rol Adı",
"addRole": "Rol Ekle",
"permissions": "Yetkiler",
"existingRole": "Bu rol zaten mevcuttur."
},
"Survey": {
"addAnswer": "Cevap Ekle",
"addSurvey": "Anket Ekle",
"addQuestion": "Soru Ekle",
"answer": "Cevap ",
"answers": "Cevaplar",
"survey": "Anket",
"surveys": "Anketler ",
"surveyName": "Anket Adı",
"question": "Soru ",
"questions": "Sorular",
"tag": "Etiket",
"value": "Değer"
},
"Contact": {
"contact": "İletişim",
"contactInfo": "İletişim Bilgileri",
"contactEmail": "E-posta Adresi",
"contactPhoneNumber": "Telefon Numarası",
"contactAddress": "Adres"
},
"MailSettings": {
"mailSettings": "E-posta Ayarları",
"editMailInfo": "E-posta Bilgilerini Düzenle",
"hostName": "Sunucu Adı",
"smtpPort": "SMTP Portu",
"emailAddress": "E-posta Adresi",
"emailPassword": "E-posta Şifresi",
"leaveBlankNote": "(Mevcut şifreyi korumak için boş bırakın)",
"mainMail": "Ana e-posta yapılandırması olarak ayarla",
"saveSettings": "Ayarları Kaydet",
"notConfigured": "E-posta yapılandırılmamış",
"noMailsRegistered": "Kayıtlı e-posta bulunamadı"
},
"Timer": {
"continue": "Devam Et ",
"expire": "Oturum süreniz dolmak üzeredir.."
},
"Users": {
"user": "Kullanıcı ",
"users": "Kullanıcılar ",
"userName": "Kullanıcı Adı ",
"addUser": "Kullanıcı Ekle",
"existingEmail": "Bu e-mail zaten mevcuttur.",
"existingPhoneNumber": "Bu telefon numarası zaten mevcuttur.",
"showDeletedUsers": "Silinen Kullanıcıları Göster"
},
"UserProfile": {
"myProfile": "Profilim",
"firstName": "Ad",
"lastName": "Soyad",
"phoneNumber": "Telefon Numarası",
"avatar": "Profil Fotoğrafı",
"status": "Durum",
"changePassword": "Şifre Değiştir",
"communicationPreferences": "İletişim Tercihleri",
"updateAvatar": "Profil Resmini Güncelle"
},
"Warnings": {
"addedFail": " Eklenirken hata meydana geldi, lütfen tekrar deneyiniz.",
"addedSuccessfully": " Başarıyla Eklendi!",
"updatedSuccessfully": " Başarıyla Güncellendi!",
"updatedFail": " Güncellenirken hata meydana geldi, lütfen tekrar deneyiniz.",
"deletedSuccessfully": " Başarıyla Silindi!",
"deletedFail": " Silinirken hata meydana geldi, lütfen tekrar deneyiniz.",
"genericUpdateFailed": "Güncelleme başarısız oldu. Lütfen tekrar deneyiniz.",
"notFound": "Bulunamadı",
"notUndone": "Bu işlem geri alınamaz!",
"required": "Tüm Alanlar Zorunludur!",
"sureForDelete": " Silmek İstediğinize Emin Misiniz?",
"uniqueName": " Benzersiz bir isim veriniz! "
},
"UserActivities": {
"title": "Kullanıcı Aktiviteleri"
},
"SystemActivities": {
"title": "Sistem Aktiviteleri"
},
"DataCenter": {
"title": "Veri Merkezleri",
"create": "Veri Merkezi Ekle",
"name": "İsim",
"namePlaceholder": "Veri merkezi ismini girin",
"externalId": "Harici ID",
"externalIdPlaceholder": "Harici ID girin",
"number": "Numara",
"numberPlaceholder": "Numara girin",
"url": "URL",
"urlPlaceholder": "URL girin",
"createSuccess": "Veri merkezi başarıyla oluşturuldu",
"deleteSuccess": "Veri merkezi başarıyla silindi",
"searchPlaceholder": "Veri merkezlerinde ara..."
},
"DataCenters": {
"title": "Veri Merkezleri",
"create": "Veri Merkezi Ekle",
"name": "İsim",
"namePlaceholder": "Veri merkezi ismini girin",
"externalId": "Harici ID",
"externalIdPlaceholder": "Harici ID girin",
"number": "Numara",
"numberPlaceholder": "Numara girin",
"url": "URL",
"urlPlaceholder": "URL girin",
"createSuccess": "Veri merkezi başarıyla oluşturuldu",
"deleteSuccess": "Veri merkezi başarıyla silindi",
"searchPlaceholder": "Veri merkezlerinde ara..."
}
}
{
"Actions": "Aksiyonlar",
"Active": "Aktif",
"ByName": "İsme Göre",
"CreatedTime": "Oluşturulma Zamanı",
"Description": " Açıklaması",
"Filter": "Filtrele",
"Management": "Yönetim",
"Passive": "Pasif",
"Show": "Göster",
"Status": "Durum",
"Time": "Zaman ",
"Activities": {
"activity": "Aktivite ",
"activities": "Aktiviteler ",
"type": "Log Tipi",
"message": "Log Mesajı"
},
"Areas": {
"addArea": "Alan Ekle",
"area": "Alan ",
"areas": "Alanlar ",
"areaName": "Alan Adı ",
"city": "Şehir ",
"cities": "Şehirler ",
"cityName": "Şehir Adı ",
"country": "Ülke ",
"countries": "Ülkeler ",
"countryName": "Ülke Adı ",
"countryCode": "Ülke Kodu ",
"district": "İlçe ",
"districts": "İlçeler",
"districtName": "İlçe Adı",
"neighborhood": "Mahalle ",
"neighborhoods": "Mahalleler ",
"neighborhoodName": "Mahalle Adı",
"addNeighborhood": "Mahalle Ekle",
"latitude": "Enlem",
"longitude": "Boylam"
},
"Auth": {
"authorized": "Devam etmek için yetkilendirilmiş kullanıcı bilgilerinizi giriniz.",
"didUForgotPassword": "Şifrenizi mi unuttunuz?",
"logout": ıkış Yap",
"logoutMessage": " Çıkış yaptınız. Yönlendiriliyorsunuz...",
"login": "Giriş Yap",
"loginMessage": " Giriş başarılı yönlendiriliyorsunuz...",
"password": "Şifre ",
"welcome": "Hoşgeldiniz",
"incorrectForm": "Kullanıcı bilgileri hatalıdır. Lütfen tekrar deneyiniz."
},
"Cruds": {
"add": " Ekle",
"cancel": " İptal",
"delete": "Sil",
"edit": "Düzenle",
"reactive": "Aktif Et",
"save": "Kaydet",
"saving": "Kaydediliyor..",
"update": "Güncelle"
},
"Common": {
"save": "Kaydet",
"cancel": "İptal",
"yes": "Evet",
"no": "Hayır",
"areYouSure": "Emin misiniz?",
"cantRevert": "Bu işlem geri alınamaz!"
},
"DataInput": {
"area": "Bölge ",
"report": "Rapor ",
"reports": "Raw Data",
"data": "Veri ",
"datas": "Veriler ",
"dataInput": "Veri Girişi",
"year": "Yıl",
"month": "Ay",
"consumptionAmount": "Tüketim Miktarı",
"consumptionUnit": "Tüketim Birimi",
"gpcReference": "GPC Referans",
"total": "Toplam ",
"save": "Veriyi Kaydet",
"update": "Veriyi Güncelle",
"showDeleted": "Silinen Raporları Göster",
"result": "Sonuç",
"directToAllDatas": "Tüm Verileri Gör",
"addNewData": "Yeni Veri Ekle",
"failUploadExcel": "Dosya yüklenirken hata oluştu!"
},
"Graphics": {
"graphics": "Raporlar",
"reports": "Raporlar"
},
"EmissionSources": {
"dataSet": "Veri Seti",
"emissionSource": "Emisyon Kaynağı ",
"emissionSources": "Emisyon Kaynakları ",
"emissionSourceName": "Emisyon Kaynağı Adı",
"addEmissionSource": "Emisyon Kaynağı Ekle",
"existingEmissionName": "Bu isimde bir emisyon kaynağı mevcuttur!",
"sector": "Veri Sektörü ",
"sectors": "Veri Sektörleri ",
"subSector": "Sektör Alt Birimi ",
"subSectors": "Sektör Alt Birimleri ",
"subUnit": "Faaliyet Alt Birimi ",
"subUnits": "Faaliyet Alt Birimleri ",
"emissionScopes": "Emisyon Kapsamı ",
"emissionFactors": "Emisyon Faktörleri ",
"showDeletedEmissionSource": "Silinen Emisyon Kaynaklarını Göster"
},
"Map": {
"map": "Harita",
"goBack": "Geri dön",
"reference": "Referans",
"title": "Harita"
},
"Months": {
"1": "Ocak",
"2": "Şubat",
"3": "Mart",
"4": "Nisan",
"5": "Mayıs",
"6": "Haziran",
"7": "Temmuz",
"8": "Ağustos",
"9": "Eylül",
"10": "Ekim",
"11": "Kasım",
"12": "Aralık",
"null": "Yıl Geneli",
"0": "Yıl Geneli"
},
"Notifications": {
"content": "İçerik ",
"notification": "Bildirim ",
"notifications": "Bildirimler ",
"showAll": "Tüm Bildirimleri Göster",
"title": "Başlık ",
"notificationType": "Bildirim Tipi "
},
"Organizations": {
"organization": "Organizasyon ",
"organizations": "Organizasyonlar",
"organizationName": "Organizasyon Adı",
"parentOrganization": "Bağlı Olduğu Organizasyon",
"childOrganization": "Alt Organizasyonu",
"addOrganization": "Organizasyon Ekle",
"existingName": "Bu isimde bir organizasyon mevcuttur!.",
"showDeletedOrganizations": "Silinen Organizasyonları Göster"
},
"PasswordLabel": {
"passwordLabel": "Şifre",
"confirmPassword": "Şifre Tekrar",
"oldPassword": "Eski Şifre",
"newPassword": "Yeni Şifre",
"newConfirmPassword": "Yeni Şifre Tekrar",
"verificationCode": "Doğrulama Kodu",
"cannotbeleftblank": " Boş Bırakılamaz ",
"passwordNotSame": "Şifreler aynı değil",
"passwordValidation": "Şifre 6-20 karakter uzunluğunda, en az 1 sayı, 1 büyük harf ve 1 küçük harf içermelidir!",
"forgotPassword": "Şifremi Unuttum",
"enterEmail": "Geçerli bir email giriniz.",
"send": "Gönder",
"redirectToReset": "Şifre sıfırlama ekranına yönlendiriliyorsunuz..",
"resetPassword": "Şifre Sıfırlama",
"resend": "Doğrulama Kodunu Tekrar Gönder",
"invalidVerificationCode": "Geçersiz doğrulama kodu!",
"redirectToLogin": "Giriş ekranına yönlendiriliyorsunuz.."
},
"Roles": {
"role": "Rol ",
"roles": "Roller",
"roleName": "Rol Adı",
"addRole": "Rol Ekle",
"permissions": "Yetkiler",
"existingRole": "Bu rol zaten mevcuttur."
},
"Survey": {
"addAnswer": "Cevap Ekle",
"addSurvey": "Anket Ekle",
"addQuestion": "Soru Ekle",
"answer": "Cevap ",
"answers": "Cevaplar",
"survey": "Anket",
"surveys": "Anketler ",
"surveyName": "Anket Adı",
"question": "Soru ",
"questions": "Sorular",
"tag": "Etiket",
"value": "Değer"
},
"Contact": {
"contact": "İletişim",
"contactInfo": "İletişim Bilgileri",
"contactEmail": "E-posta Adresi",
"contactPhoneNumber": "Telefon Numarası",
"contactAddress": "Adres"
},
"MailSettings": {
"mailSettings": "E-posta Ayarları",
"editMailInfo": "E-posta Bilgilerini Düzenle",
"hostName": "Sunucu Adı",
"smtpPort": "SMTP Portu",
"emailAddress": "E-posta Adresi",
"emailPassword": "E-posta Şifresi",
"leaveBlankNote": "(Mevcut şifreyi korumak için boş bırakın)",
"mainMail": "Ana e-posta yapılandırması olarak ayarla",
"saveSettings": "Ayarları Kaydet",
"notConfigured": "E-posta yapılandırılmamış",
"noMailsRegistered": "Kayıtlı e-posta bulunamadı"
},
"Timer": {
"continue": "Devam Et ",
"expire": "Oturum süreniz dolmak üzeredir.."
},
"Users": {
"user": "Kullanıcı ",
"users": "Kullanıcılar ",
"userName": "Kullanıcı Adı ",
"addUser": "Kullanıcı Ekle",
"existingEmail": "Bu e-mail zaten mevcuttur.",
"existingPhoneNumber": "Bu telefon numarası zaten mevcuttur.",
"showDeletedUsers": "Silinen Kullanıcıları Göster"
},
"UserProfile": {
"myProfile": "Profilim",
"firstName": "Ad",
"lastName": "Soyad",
"phoneNumber": "Telefon Numarası",
"avatar": "Profil Fotoğrafı",
"status": "Durum",
"changePassword": "Şifre Değiştir",
"communicationPreferences": "İletişim Tercihleri",
"updateAvatar": "Profil Resmini Güncelle"
},
"Warnings": {
"addedFail": " Eklenirken hata meydana geldi, lütfen tekrar deneyiniz.",
"addedSuccessfully": " Başarıyla Eklendi!",
"updatedSuccessfully": " Başarıyla Güncellendi!",
"updatedFail": " Güncellenirken hata meydana geldi, lütfen tekrar deneyiniz.",
"deletedSuccessfully": " Başarıyla Silindi!",
"deletedFail": " Silinirken hata meydana geldi, lütfen tekrar deneyiniz.",
"genericUpdateFailed": "Güncelleme başarısız oldu. Lütfen tekrar deneyiniz.",
"notFound": "Bulunamadı",
"notUndone": "Bu işlem geri alınamaz!",
"required": "Tüm Alanlar Zorunludur!",
"sureForDelete": " Silmek İstediğinize Emin Misiniz?",
"uniqueName": " Benzersiz bir isim veriniz! "
},
"UserActivities": {
"title": "Kullanıcı Aktiviteleri"
},
"SystemActivities": {
"title": "Sistem Aktiviteleri"
},
"DataCenter": {
"title": "Veri Merkezleri",
"create": "Veri Merkezi Ekle",
"name": "İsim",
"namePlaceholder": "Veri merkezi ismini girin",
"externalId": "Harici ID",
"externalIdPlaceholder": "Harici ID girin",
"number": "Numara",
"numberPlaceholder": "Numara girin",
"url": "URL",
"urlPlaceholder": "URL girin",
"createSuccess": "Veri merkezi başarıyla oluşturuldu",
"deleteSuccess": "Veri merkezi başarıyla silindi",
"searchPlaceholder": "Veri merkezlerinde ara..."
},
"DataCenters": {
"title": "Veri Merkezleri",
"create": "Veri Merkezi Ekle",
"name": "İsim",
"namePlaceholder": "Veri merkezi ismini girin",
"externalId": "Harici ID",
"externalIdPlaceholder": "Harici ID girin",
"number": "Numara",
"numberPlaceholder": "Numara girin",
"url": "URL",
"urlPlaceholder": "URL girin",
"createSuccess": "Veri merkezi başarıyla oluşturuldu",
"deleteSuccess": "Veri merkezi başarıyla silindi",
"searchPlaceholder": "Veri merkezlerinde ara..."
}
}

View File

@@ -49,9 +49,9 @@ export default [
permissionCheck("paginate_roles_get")) && [
{
id: "Organizations",
title: "DataCenters.title",
title: "Data Center Management",
icon: <Home size={20} />,
navLink: "/organizasyonlar",
navLink: "/veri-merkezi-yonetimi",
display: (permissionCheck("paginate_datacenters_get") ||
permissionCheck("data_center_create") ||
permissionCheck("data_center_update") ||
@@ -142,9 +142,63 @@ export default [
},
{
id: "DataCenter",
title: "Data Centers",
title: "Data Center Overview",
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",

View File

@@ -49,9 +49,9 @@ export default [
permissionCheck("paginate_roles_get")) && [
{
id: "DataCenters",
title: "DataCenters.title",
title: "Data Center Management",
icon: <Zap size={20} />,
navLink: "/organizasyonlar",
navLink: "/veri-merkezi-yonetimi",
display: (permissionCheck("paginate_datacenters_get") ||
permissionCheck("data_center_create") ||
permissionCheck("data_center_update") ||
@@ -142,9 +142,63 @@ export default [
},
{
id: "DataCenter",
title: "DataCenters",
title: "Data Center Overview",
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",

View File

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

View File

@@ -34,30 +34,69 @@ export const getDataCenters = () => {
latitude
longitude
area {
tag
name
cityId
districtId
}
projects {
id
name
physicalMachines {
tag
cities {
id
name
vms {
active {
id
status
name
power
config {
id
cpu
ram
disk
}
}
}
districts {
id
name
}
}
city {
id
name
}
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:", {
status: response.status,
data: response.data,
errors: response.data?.errors
errors: response.data?.errors,
});
// Check for GraphQL errors
@@ -91,7 +130,7 @@ export const getDataCenters = () => {
}
const dataCenters = response.data.data.dataCenters;
// Validate dataCenters is an array
if (!Array.isArray(dataCenters)) {
throw new Error("Invalid response: dataCenters is not an array");
@@ -110,7 +149,7 @@ export const getDataCenters = () => {
message: error.message,
response: error.response?.data,
status: error.response?.status,
stack: error.stack
stack: error.stack,
});
// Check for specific error types
@@ -155,10 +194,50 @@ export const createDataCenter = (dataCenterData) => {
latitude
longitude
area {
id
tag
cities {
id
name
}
districts {
id
name
}
}
city {
id
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),
ayposURL: dataCenterData.ayposURL || "",
number: parseInt(dataCenterData.number) || 1,
areaId: dataCenterData.areaId,
areaId: dataCenterData.areaId || null,
cityId: dataCenterData.cityId || null,
address: dataCenterData.address || "",
latitude: dataCenterData.latitude ? parseFloat(dataCenterData.latitude) : null,
longitude: dataCenterData.longitude ? parseFloat(dataCenterData.longitude) : null,
city: dataCenterData.city
}
}
latitude: dataCenterData.latitude
? parseFloat(dataCenterData.latitude)
: 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: {
@@ -188,7 +277,7 @@ export const createDataCenter = (dataCenterData) => {
console.log("Create Response:", {
status: response.status,
data: response.data,
errors: response.data?.errors
errors: response.data?.errors,
});
if (response.data?.errors) {
@@ -240,10 +329,50 @@ export const updateDataCenter = (id, dataCenterData) => {
latitude
longitude
area {
id
tag
cities {
id
name
}
districts {
id
name
}
}
city {
id
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),
ayposURL: dataCenterData.ayposURL || "",
number: parseInt(dataCenterData.number) || 1,
areaId: dataCenterData.areaId,
areaId: dataCenterData.areaId || null,
cityId: dataCenterData.cityId || null,
address: dataCenterData.address || "",
latitude: dataCenterData.latitude ? parseFloat(dataCenterData.latitude) : null,
longitude: dataCenterData.longitude ? parseFloat(dataCenterData.longitude) : null,
city: dataCenterData.city
}
}
latitude: dataCenterData.latitude
? parseFloat(dataCenterData.latitude)
: 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: {
@@ -276,7 +415,7 @@ export const updateDataCenter = (id, dataCenterData) => {
dispatch({
type: "UPDATE_DATA_CENTER_SUCCESS",
payload: response.data.data.updateDataCenter
payload: response.data.data.updateDataCenter,
});
return response.data.data.updateDataCenter;
@@ -309,8 +448,8 @@ export const deleteDataCenter = (id) => {
}
`,
variables: {
id: id
}
id: id,
},
},
{
headers: {
@@ -325,7 +464,7 @@ export const deleteDataCenter = (id) => {
dispatch({
type: "DELETE_DATA_CENTER_SUCCESS",
payload: id
payload: id,
});
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) => {
return new Promise(async (resolve, reject) => {
// Don't make the request if dataCenterId is undefined, null, or empty
if (!dataCenterId || dataCenterId === "undefined") {
console.log('getDataCenterVMs: No dataCenterId provided');
console.log("getDataCenterVMs: No dataCenterId provided");
resolve([]);
return;
}
try {
console.log('getDataCenterVMs: Fetching VMs for data center:', dataCenterId);
const response = await ApplicationService.http()
.post(
"/graphql",
{
query: `
console.log(
"getDataCenterVMs: Fetching VMs for data center:",
dataCenterId
);
const response = await ApplicationService.http().post(
"/graphql",
{
query: `
{
dataCenter(id: "${dataCenterId}") {
id
dataCenter
projects {
physicalMachines {
id
name
physicalMachines {
vms {
id
name
vms {
id
name
status
power
}
vmName
state
power
}
}
}
}
`,
},
{
headers: {
Authorization: "Bearer " + localStorage.getItem("accessToken"),
},
{
headers: {
Authorization: "Bearer " + localStorage.getItem("accessToken"),
},
}
);
}
);
const dataCenter = response?.data?.data?.dataCenter;
console.log('getDataCenterVMs: Data center response:', dataCenter);
console.log("getDataCenterVMs: Data center response:", dataCenter);
let allVMs = [];
if (dataCenter && dataCenter.projects) {
dataCenter.projects.forEach(project => {
if (project.physicalMachines) {
project.physicalMachines.forEach(pm => {
if (pm.vms) {
allVMs = allVMs.concat(pm.vms);
}
});
if (dataCenter && dataCenter.physicalMachines) {
dataCenter.physicalMachines.forEach((pm) => {
if (pm.vms) {
allVMs = allVMs.concat(pm.vms);
}
});
}
console.log('getDataCenterVMs: Found VMs:', allVMs);
console.log("getDataCenterVMs: Found VMs:", allVMs);
resolve(allVMs);
} catch (error) {
console.error("Error fetching VMs by data center:", error);

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -1,218 +1,218 @@
import React, { useEffect, useState } from "react";
import {
Button,
Card,
CardHeader,
CardTitle,
Col,
Modal,
ModalBody,
ModalHeader,
Row,
UncontrolledTooltip, // Add UncontrolledTooltip import
} from "reactstrap";
import { Edit, Mail, Phone, MapPin } from "react-feather"; // Import Mail, Phone, MapPin
import { useSnackbar } from "notistack";
import { useTranslation } from "react-i18next";
import { useDispatch, useSelector } from "react-redux";
import { permissionCheck } from "../components/permission-check";
import {
getMailSettings,
clearMailSuccess,
clearMailError,
} from "../redux/actions/mailSettings";
import MailSettings from "./MailSettings";
import SpinnerComponent from "../@core/components/spinner/Fallback-spinner";
// Import custom styles for the communication page
import "../assets/scss/pages/communication.scss";
function Communication() {
const { t } = useTranslation();
const dispatch = useDispatch();
const { enqueueSnackbar } = useSnackbar();
const { currentSettings, loading, success, error } = useSelector(
// Add loading to useSelector
(state) => state.mailSettings
);
const [showMailModal, setShowMailModal] = useState(false);
useEffect(() => {
// Load mail settings once when component mounts
dispatch(getMailSettings());
}, [dispatch]);
useEffect(() => {
if (success) {
enqueueSnackbar(t("Warnings.updatedSuccessfully"), {
variant: "success",
});
dispatch(clearMailSuccess());
}
}, [success, enqueueSnackbar, t, dispatch]);
useEffect(() => {
if (error) {
const errorMessage =
error?.graphQLErrors?.[0]?.message ||
error?.message ||
t("Warnings.genericUpdateFailed");
enqueueSnackbar(errorMessage, {
variant: "error",
});
dispatch(clearMailError());
}
}, [error, enqueueSnackbar, t, dispatch]);
// Get email address from settings or use default from environment variable
const defaultEmail = process.env.REACT_APP_DEFAULT_EMAIL || "";
// Use default email if currentSettings is null or emailAddress is null
const emailAddress = currentSettings?.emailAddress || defaultEmail;
const handleEmailClick = () => {
if (emailAddress) {
window.location.href = `mailto:${emailAddress}`;
}
};
const handleCloseModal = () => {
setShowMailModal(false);
};
return (
<div style={{ marginTop: "2%" }}>
{loading && !currentSettings ? (
<div
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
minHeight: 200,
}}
>
<SpinnerComponent />
</div>
) : (
<>
{permissionCheck("settings_access") && (
<>
<Modal
isOpen={showMailModal}
toggle={handleCloseModal}
className="modal-dialog-centered"
size="lg"
>
<ModalHeader toggle={handleCloseModal}>
{t("MailSettings.editMailInfo")}
</ModalHeader>
<ModalBody>
<MailSettings closeModal={handleCloseModal} />
</ModalBody>
</Modal>
</>
)}
<Card className="border-bottom">
<CardHeader className="border-bottom">
<CardTitle tag="h2" className="row ml-md-2 align-items-center">
{t("Contact.contactInfo")}
</CardTitle>
</CardHeader>
<Row>
<Col className="pl-md-5 pl-2 col-md-6 col-12">
<Row className="mx-0 mt-1">
<Col sm="6" md="5" className="mr-2">
<div className="email-container d-flex align-items-center justify-content-between">
<div>
<h4>
<Mail size={16} className="mr-1" />{" "}
{t("Contact.contactEmail")}
</h4>{" "}
{/* Add Mail icon */}
<p
style={{
color: emailAddress ? "blue" : "inherit",
textDecoration: emailAddress ? "underline" : "none",
cursor: emailAddress ? "pointer" : "default",
}}
onClick={handleEmailClick}
>
{emailAddress ||
defaultEmail ||
t("MailSettings.notConfigured")}
</p>
</div>
{permissionCheck("settings_access") && (
<>
{" "}
{/* Wrap button and tooltip in fragment */}
<Button
color="flat-primary"
className="btn-icon"
onClick={() => setShowMailModal(true)}
id="edit-email-btn" // Add id for tooltip
>
<Edit size={18} />
</Button>
<UncontrolledTooltip
placement="top"
target="edit-email-btn" // Target the button id
timeout={150} // Add timeout prop to fix the warning
>
{t("MailSettings.editMailInfo")}{" "}
{/* Tooltip text */}
</UncontrolledTooltip>
</>
)}
</div>
</Col>
<Col sm="6" md="5" className="mr-2">
<div className="telephone-container">
<h4>
<Phone size={16} className="mr-1" />{" "}
{t("Contact.contactPhoneNumber")}
</h4>{" "}
{/* Add Phone icon */}
<p>+90 507 750 00 41</p>
</div>
</Col>
</Row>
<Row className="mx-0 mt-4">
<Col sm="6" md="5" className="mr-2">
<div className="address-container">
<h4>
<MapPin size={16} className="mr-1" />{" "}
{t("Contact.contactAddress")}
</h4>{" "}
{/* Add MapPin icon */}
<address>
Central Office: 4995 sokak no:3, Alacaatlı Mahallesi,
Daire No: A2 06810 Çankaya/Ankara
</address>
</div>
</Col>
</Row>
</Col>
<Col className="pl-md-5 pl-2 col-md-6 col-12 pb-2 border-left">
<Row className="mx-0 mt-1">
<div className="address-map w-100">
<div className="responsive-map-container">
<iframe
src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3063.1752741150003!2d32.658217075858445!3d39.847904971536735!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x14d33eef6ee44755%3A0x77faea5f08f32c60!2zTUVBIEfDnFpFTEJBSMOHRU0!5e0!3m2!1sen!2str!4v1741165773414!5m2!1sen!2str"
allowFullScreen=""
loading="lazy"
referrerPolicy="no-referrer-when-downgrade"
></iframe>
</div>
</div>
</Row>
</Col>
</Row>
</Card>
</>
)}
</div>
);
}
export default Communication;
import React, { useEffect, useState } from "react";
import {
Button,
Card,
CardHeader,
CardTitle,
Col,
Modal,
ModalBody,
ModalHeader,
Row,
UncontrolledTooltip, // Add UncontrolledTooltip import
} from "reactstrap";
import { Edit, Mail, Phone, MapPin } from "react-feather"; // Import Mail, Phone, MapPin
import { useSnackbar } from "notistack";
import { useTranslation } from "react-i18next";
import { useDispatch, useSelector } from "react-redux";
import { permissionCheck } from "../components/permission-check";
import {
getMailSettings,
clearMailSuccess,
clearMailError,
} from "../redux/actions/mailSettings";
import MailSettings from "./MailSettings";
import SpinnerComponent from "../@core/components/spinner/Fallback-spinner";
// Import custom styles for the communication page
import "../assets/scss/pages/communication.scss";
function Communication() {
const { t } = useTranslation();
const dispatch = useDispatch();
const { enqueueSnackbar } = useSnackbar();
const { currentSettings, loading, success, error } = useSelector(
// Add loading to useSelector
(state) => state.mailSettings
);
const [showMailModal, setShowMailModal] = useState(false);
useEffect(() => {
// Load mail settings once when component mounts
dispatch(getMailSettings());
}, [dispatch]);
useEffect(() => {
if (success) {
enqueueSnackbar(t("Warnings.updatedSuccessfully"), {
variant: "success",
});
dispatch(clearMailSuccess());
}
}, [success, enqueueSnackbar, t, dispatch]);
useEffect(() => {
if (error) {
const errorMessage =
error?.graphQLErrors?.[0]?.message ||
error?.message ||
t("Warnings.genericUpdateFailed");
enqueueSnackbar(errorMessage, {
variant: "error",
});
dispatch(clearMailError());
}
}, [error, enqueueSnackbar, t, dispatch]);
// Get email address from settings or use default from environment variable
const defaultEmail = process.env.REACT_APP_DEFAULT_EMAIL || "";
// Use default email if currentSettings is null or emailAddress is null
const emailAddress = currentSettings?.emailAddress || defaultEmail;
const handleEmailClick = () => {
if (emailAddress) {
window.location.href = `mailto:${emailAddress}`;
}
};
const handleCloseModal = () => {
setShowMailModal(false);
};
return (
<div style={{ marginTop: "2%" }}>
{loading && !currentSettings ? (
<div
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
minHeight: 200,
}}
>
<SpinnerComponent />
</div>
) : (
<>
{permissionCheck("settings_access") && (
<>
<Modal
isOpen={showMailModal}
toggle={handleCloseModal}
className="modal-dialog-centered"
size="lg"
>
<ModalHeader toggle={handleCloseModal}>
{t("MailSettings.editMailInfo")}
</ModalHeader>
<ModalBody>
<MailSettings closeModal={handleCloseModal} />
</ModalBody>
</Modal>
</>
)}
<Card className="border-bottom">
<CardHeader className="border-bottom">
<CardTitle tag="h2" className="row ml-md-2 align-items-center">
{t("Contact.contactInfo")}
</CardTitle>
</CardHeader>
<Row>
<Col className="pl-md-5 pl-2 col-md-6 col-12">
<Row className="mx-0 mt-1">
<Col sm="6" md="5" className="mr-2">
<div className="email-container d-flex align-items-center justify-content-between">
<div>
<h4>
<Mail size={16} className="mr-1" />{" "}
{t("Contact.contactEmail")}
</h4>{" "}
{/* Add Mail icon */}
<p
style={{
color: emailAddress ? "blue" : "inherit",
textDecoration: emailAddress ? "underline" : "none",
cursor: emailAddress ? "pointer" : "default",
}}
onClick={handleEmailClick}
>
{emailAddress ||
defaultEmail ||
t("MailSettings.notConfigured")}
</p>
</div>
{permissionCheck("settings_access") && (
<>
{" "}
{/* Wrap button and tooltip in fragment */}
<Button
color="flat-primary"
className="btn-icon"
onClick={() => setShowMailModal(true)}
id="edit-email-btn" // Add id for tooltip
>
<Edit size={18} />
</Button>
<UncontrolledTooltip
placement="top"
target="edit-email-btn" // Target the button id
timeout={150} // Add timeout prop to fix the warning
>
{t("MailSettings.editMailInfo")}{" "}
{/* Tooltip text */}
</UncontrolledTooltip>
</>
)}
</div>
</Col>
<Col sm="6" md="5" className="mr-2">
<div className="telephone-container">
<h4>
<Phone size={16} className="mr-1" />{" "}
{t("Contact.contactPhoneNumber")}
</h4>{" "}
{/* Add Phone icon */}
<p>+90 507 750 00 41</p>
</div>
</Col>
</Row>
<Row className="mx-0 mt-4">
<Col sm="6" md="5" className="mr-2">
<div className="address-container">
<h4>
<MapPin size={16} className="mr-1" />{" "}
{t("Contact.contactAddress")}
</h4>{" "}
{/* Add MapPin icon */}
<address>
Central Office: 4995 sokak no:3, Alacaatlı Mahallesi,
Daire No: A2 06820 Çankaya/Ankara
</address>
</div>
</Col>
</Row>
</Col>
<Col className="pl-md-5 pl-2 col-md-6 col-12 pb-2 border-left">
<Row className="mx-0 mt-1">
<div className="address-map w-100">
<div className="responsive-map-container">
<iframe
src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3063.1752741150003!2d32.658217075858445!3d39.847904971536735!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x14d33eef6ee44755%3A0x77faea5f08f32c60!2zTUVBIEfDnFpFTEJBSMOHRU0!5e0!3m2!1sen!2str!4v1741165773414!5m2!1sen!2str"
allowFullScreen=""
loading="lazy"
referrerPolicy="no-referrer-when-downgrade"
></iframe>
</div>
</div>
</Row>
</Col>
</Row>
</Card>
</>
)}
</div>
);
}
export default Communication;

View File

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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

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 { useDispatch, useSelector } from "react-redux";
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 { getDataCenters } from "../../redux/actions/dataCenter";
import { editNumbers } from "../../components/edit-numbers";
import Select from "react-select";
function MainDataTables() {
const { t } = useTranslation();
const dispatch = useDispatch();
const mainDataTablesStore = useSelector((state) => state.mainDataTables);
const dataCenterStore = useSelector((state) => state.dataCenter);
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(() => {
try {
// Fetch VM emission data
dispatch(getVMEmissionSummary());
} catch (err) {
console.error('Error in MainDataTables:', err);
setError(err.message);
}
dispatch(getDataCenters());
}, [dispatch]);
// Debug log for store data
// Update datacenter options when datacenters are loaded
useEffect(() => {
console.log('Current store data:', mainDataTablesStore);
}, [mainDataTablesStore]);
if (dataCenterStore?.dataCenters?.length > 0) {
const options = dataCenterStore.dataCenters.map((dataCenter) => ({
value: dataCenter.id,
label: dataCenter.dataCenter,
externalId: dataCenter.externalId,
}));
setDataCenterOptions(options);
}
}, [dataCenterStore?.dataCenters]);
const columns = [
{
header: "VM ID",
accessorKey: "vmId",
Cell: ({ cell }) => <span>{cell.getValue() || "-"}</span>,
},
{
header: "Data Center",
accessorKey: "dataCenter",
Cell: ({ cell }) => <span>{cell.getValue() || "-"}</span>,
},
{
header: "Project",
accessorKey: "project",
Cell: ({ cell }) => <span>{cell.getValue() || "-"}</span>,
},
{
header: "Physical Machine",
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>
),
},
];
// Fetch VM emission data when datacenter is selected
useEffect(() => {
if (selectedDataCenter?.value) {
const fetchData = async () => {
try {
setLoading(true);
setError(null);
await dispatch(getVMEmissionSummary(selectedDataCenter.value));
} catch (err) {
console.error("Error in MainDataTables:", err);
setError(err.message);
} finally {
setLoading(false);
}
};
fetchData();
}
}, [selectedDataCenter, dispatch]);
const tableData = mainDataTablesStore?.vmEmissionSummary || [];
console.log('VM Emission data:', tableData);
// Memoize columns to prevent re-renders
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) {
return (
@@ -109,37 +165,109 @@ function MainDataTables() {
<div style={{ marginTop: "2%" }}>
<Card>
<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>
<MaterialReactTable
columns={columns}
data={tableData}
enableColumnFilters={true}
enableFilters={true}
enableGlobalFilter={true}
enablePagination={true}
enableColumnResizing={true}
enableStickyHeader={true}
muiTableContainerProps={{ sx: { maxHeight: 'calc(100vh - 180px)' } }}
muiTableProps={{
sx: {
tableLayout: 'auto',
},
}}
initialState={{
pagination: {
pageSize: 100,
pageIndex: 0
},
sorting: [
{ id: 'dataCenter', desc: false }
],
density: 'compact'
}}
state={{
isLoading: !mainDataTablesStore?.vmEmissionSummary
}}
/>
{/* Datacenter Selection */}
<div className="p-3 border-bottom">
<Row>
<Col md="6">
<Label for="datacenter-select">{t("Data Center")}</Label>
<Select
id="datacenter-select"
value={selectedDataCenter}
onChange={setSelectedDataCenter}
options={dataCenterOptions}
placeholder={t("Select a data center...")}
isClearable
isSearchable
isLoading={dataCenterStore?.loading}
noOptionsMessage={() => t("No data centers available")}
styles={{
menu: (provided) => ({
...provided,
zIndex: 9999, // Ensure dropdown appears above other elements
}),
}}
menuPortalTarget={document.body} // Render dropdown in body to avoid container overflow
/>
</Col>
</Row>
</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>
</div>
);

View File

@@ -32,15 +32,87 @@ import { getCities } from "../redux/actions/cities";
import { v4 as uuidv4 } from "uuid";
import { getCity } from "../redux/actions/city";
import { getDistrict } from "../redux/actions/district";
import {
getOrganisations,
getOrganisationById,
} from "../redux/actions/organisations";
// import {
// getOrganisations,
// getOrganisationById,
// } from "../redux/actions/organisations";
import { getAreasWithCriteria } from "../redux/actions/areas";
import { ChromePicker } from "react-color";
import { customFilterForSelect } from "../utility/Utils";
import { permissionCheck } from "../components/permission-check";
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 [showColorPicker, setShowColorPicker] = useState(false);
@@ -117,20 +189,20 @@ const Map = () => {
const citiesStore = useSelector((state) => state.cities);
const cityStore = useSelector((state) => state.city);
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 dataCenterStore = useSelector((state) => state.dataCenter);
const [cities, setCities] = useState([]);
const [districts, setDistricts] = useState([]);
const [neighborhoods, setNeighborhoods] = useState([]);
const [organizationOptions, setOrganizationOptions] = useState([]);
const organizationId = localStorage.getItem("organizationId");
const roleTag = localStorage.getItem("roleTag");
const [selectedOrganization, setSelectedOrganization] = useState({
label: localStorage.getItem("organizationName"),
value: organizationId,
});
// const [organizationOptions, setOrganizationOptions] = useState([]);
// const organizationId = localStorage.getItem("organizationId");
// const roleTag = localStorage.getItem("roleTag");
// const [selectedOrganization, setSelectedOrganization] = useState({
// label: localStorage.getItem("organizationName"),
// value: organizationId,
// });
const [areasOptions, setAreasOptions] = useState([]);
const [done, setDone] = useState(false);
@@ -146,7 +218,7 @@ const Map = () => {
const [showDataInputModal, setShowDataInputModal] = useState(false);
const [inputData, setInputData] = useState({
organization: selectedOrganization,
// organization: selectedOrganization,
});
const [referance, setReferance] = useState(
Number(localStorage.getItem("referance")) || 1000
@@ -176,15 +248,17 @@ const Map = () => {
dispatch(getDataCenters());
}, []);
useEffect(() => {
if (selectedOrganization?.value != "undefined") {
dispatch(getAreasWithCriteria(selectedOrganization.value));
}
}, [selectedOrganization]);
// useEffect(() => {
// if (selectedOrganization?.value != "undefined") {
// dispatch(getAreasWithCriteria(selectedOrganization.value));
// }
// }, [selectedOrganization]);
useEffect(() => {
setAreasOptions([]);
// Load all areas without organization filter for now
// You may want to add organization filtering back later if needed
const citiesOptions =
areasStore?.areasWithCriteria
?.map((area) =>
@@ -235,13 +309,13 @@ const Map = () => {
]);
}, [areasStore]);
useEffect(() => {
if (roleTag === "SUPER_ADMIN") {
dispatch(getOrganisations());
} else {
dispatch(getOrganisationById(organizationId));
}
}, []);
// useEffect(() => {
// if (roleTag === "SUPER_ADMIN") {
// dispatch(getOrganisations());
// } else {
// dispatch(getOrganisationById(organizationId));
// }
// }, []);
const handleDataInputButtonPressed = ({ area, type }) => {
const areaName =
@@ -348,38 +422,38 @@ const Map = () => {
});
}, [selectedDistrict, districtStore?.district, year.value]);
useEffect(() => {
let organizationOptions = [];
// useEffect(() => {
// let organizationOptions = [];
if (
OrganisationsStore.organization &&
OrganisationsStore.organization.length !== 0
) {
organizationOptions.push({
value: OrganisationsStore.organization.id,
label: OrganisationsStore.organization.tag,
});
// if (
// OrganisationsStore.organization &&
// OrganisationsStore.organization.length !== 0
// ) {
// organizationOptions.push({
// value: OrganisationsStore.organization.id,
// label: OrganisationsStore.organization.tag,
// });
if (OrganisationsStore.organization.children) {
organizationOptions = [
...organizationOptions,
...OrganisationsStore.organization.children.map((organization) => ({
value: organization.child.id,
label: organization.child.tag,
})),
];
}
} else {
organizationOptions = OrganisationsStore.dataOrganization.map(
(organization) => ({
value: organization.id,
label: organization.tag,
})
);
}
// if (OrganisationsStore.organization.children) {
// organizationOptions = [
// ...organizationOptions,
// ...OrganisationsStore.organization.children.map((organization) => ({
// value: organization.child.id,
// label: organization.child.tag,
// })),
// ];
// }
// } else {
// organizationOptions = OrganisationsStore.dataOrganization.map(
// (organization) => ({
// value: organization.id,
// label: organization.tag,
// })
// );
// }
setOrganizationOptions(organizationOptions);
}, [OrganisationsStore]);
// setOrganizationOptions(organizationOptions);
// }, [OrganisationsStore]);
const renderDataInputModal = () => {
return (
@@ -623,29 +697,60 @@ const Map = () => {
<LayerGroup>
{dataCenterStore.dataCenters.map((dc) => {
if (!dc.latitude || !dc.longitude) return null;
return (
<Marker
key={dc.id}
<Marker
key={dc.id}
position={[dc.latitude, dc.longitude]}
icon={dataCenterIcon}
>
<Popup>
<div className="data-center-popup">
<h5 className="mb-2">{dc.dataCenter}</h5>
<p className="mb-1"><strong>{t('DataCenter.number')}:</strong> {dc.number}</p>
<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 && (
<h5 className="mb-2 text-primary">{dc.dataCenter}</h5>
<div className="mb-2">
<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>
)}
{dc.ayposURL && (
<Button
className="w-100 mb-1"
color="primary"
onClick={() => window.open(dc.ayposURL, '_blank')}
onClick={() => window.open(dc.ayposURL, "_blank")}
>
Dashboard
</Button>
@@ -699,7 +804,9 @@ const Map = () => {
setDistrictView(true);
setZoom(8.0);
let convertCordinates = convertCoordinates(city.coordinates);
let convertCordinates = convertCoordinates(
city.coordinates
);
let length = convertCordinates[0][0][0].length;
let mlength = ((length + 1) / 2).toFixed(0);
let lat1 = convertCordinates[0][0][0][0];
@@ -710,7 +817,7 @@ const Map = () => {
lat: ((lat1 + lat2) / 2).toFixed(2),
lng: ((lng1 + lng2) / 2).toFixed(2),
});
}
},
}}
>
<Tooltip permanent direction="center">