231 Commits

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

View File

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

24
config.conf Normal file
View File

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

110
deploy.sh Executable file
View File

@@ -0,0 +1,110 @@
#!/bin/bash
set -euo pipefail
cd /home/ubuntu/Bgreen/sgeUpdated
# -----------------------
# Harbor settings
# -----------------------
HARBOR_REGISTRY="10.150.1.166"
HARBOR_PROJECT="bgreen"
BACKEND_IMAGE_REPO="${HARBOR_REGISTRY}/${HARBOR_PROJECT}/bgreen-backend"
FRONTEND_IMAGE_REPO="${HARBOR_REGISTRY}/${HARBOR_PROJECT}/bgreen-frontend"
# Tag images with git commit (better than latest; enables rollback)
VERSION="$(git rev-parse --short HEAD)"
echo "📦 Fetching latest changes from origin/main..."
git fetch myfork main
# Detect which files changed between local HEAD and the latest remote version
CHANGED_FILES=$(git diff --name-only HEAD myfork/main || true)
if [ -z "$CHANGED_FILES" ]; then
echo "✅ No file changes detected between HEAD and origin/main."
else
echo "🪶 Changed files:"
echo "$CHANGED_FILES"
fi
# Update to the latest version
git reset --hard myfork/main
BACKEND_CHANGED=false
FRONTEND_CHANGED=false
# Check if backend folder changed (excluding README.md)
if echo "$CHANGED_FILES" | grep "^sge-backend/" | grep -qv "README.md$"; then
BACKEND_CHANGED=true
fi
# Check if frontend folder changed (excluding README.md)
if echo "$CHANGED_FILES" | grep "^sge-frontend/" | grep -qv "README.md$"; then
FRONTEND_CHANGED=true
fi
# -----------------------
# Backend section
# -----------------------
if [ "$BACKEND_CHANGED" = true ]; then
echo "⚡ Backend changes detected."
cd sge-backend
echo "Running Maven build..."
/opt/apache-maven-3.9.11/bin/mvn clean install -DskipTests
echo "🐳 Building backend Docker image..."
docker build -t "${BACKEND_IMAGE_REPO}:${VERSION}" .
echo "📤 Pushing backend image to Harbor..."
docker push "${BACKEND_IMAGE_REPO}:${VERSION}"
echo "📥 Pulling backend image from Harbor (to ensure registry is source of truth)..."
docker pull "${BACKEND_IMAGE_REPO}:${VERSION}"
cd ..
echo "🚀 Recreating backend container using Harbor image..."
VERSION="$VERSION" docker compose up -d bgreen-backend
else
echo "✅ No backend changes."
fi
# -----------------------
# Frontend section
# -----------------------
if [ "$FRONTEND_CHANGED" = true ]; then
echo "⚡ Frontend changes detected."
cd sge-frontend
# Check if package.json or package-lock.json changed
if echo "$CHANGED_FILES" | grep -qE "^sge-frontend/(package\.json|package-lock\.json)$"; then
echo "📦 package.json changed. Running 'npm install' and 'npm run build'..."
npm install
npm run build
else
echo "📦 only code changes. Running 'npm run build'..."
npm run build
fi
echo "🐳 Building frontend Docker image..."
docker build -t "${FRONTEND_IMAGE_REPO}:${VERSION}" .
echo "📤 Pushing frontend image to Harbor..."
docker push "${FRONTEND_IMAGE_REPO}:${VERSION}"
echo "📥 Pulling frontend image from Harbor (to ensure registry is source of truth)..."
docker pull "${FRONTEND_IMAGE_REPO}:${VERSION}"
cd ..
echo "🚀 Recreating frontend container using Harbor image..."
VERSION="$VERSION" docker compose up -d bgreen-frontend
else
echo "✅ No frontend changes."
fi
echo "✅ Deployment complete."

69
deploy.sh.save Executable file
View File

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

39
docker-compose.yml Normal file
View File

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

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

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

View File

@@ -6,12 +6,12 @@
<parent>
<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>
<artifactId>sgs</artifactId>
<version>0.0.1-SNAPSHOT</version>
<version>0.0.2-SNAPSHOT</version>
<name>sgs</name>
<description>SGS project for Spring Boot</description>
<properties>

File diff suppressed because it is too large Load Diff

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.1",
"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">