diff --git a/sge-backend/src/main/java/com/sgs/graphql/dataCenter/mutation/input/DataCenterCreateInput.java b/sge-backend/src/main/java/com/sgs/graphql/dataCenter/mutation/input/DataCenterCreateInput.java
index 057e22b..b3defbb 100644
--- a/sge-backend/src/main/java/com/sgs/graphql/dataCenter/mutation/input/DataCenterCreateInput.java
+++ b/sge-backend/src/main/java/com/sgs/graphql/dataCenter/mutation/input/DataCenterCreateInput.java
@@ -15,7 +15,6 @@ public class DataCenterCreateInput extends BaseCreateInput {
private Integer number;
private Double consuptionAmount;
- @NotNull(message = "Alan ID gereklidir")
private UUID areaId;
@NotNull(message = "Sektör ID gereklidir")
diff --git a/sge-backend/src/main/java/com/sgs/graphql/dataCenter/mutation/input/DataCenterUpdateInput.java b/sge-backend/src/main/java/com/sgs/graphql/dataCenter/mutation/input/DataCenterUpdateInput.java
index 7c44336..9e34544 100644
--- a/sge-backend/src/main/java/com/sgs/graphql/dataCenter/mutation/input/DataCenterUpdateInput.java
+++ b/sge-backend/src/main/java/com/sgs/graphql/dataCenter/mutation/input/DataCenterUpdateInput.java
@@ -1,6 +1,7 @@
package com.sgs.graphql.dataCenter.mutation.input;
import com.sgs.lib.dao.mutation.input.BaseUpdateInput;
+import javax.validation.constraints.NotNull;
import java.util.UUID;
public class DataCenterUpdateInput extends BaseUpdateInput {
@@ -10,6 +11,7 @@ public class DataCenterUpdateInput extends BaseUpdateInput {
private Double consuptionAmount;
private UUID areaId;
+ @NotNull(message = "Sektör ID gereklidir")
private UUID sectorId;
private UUID subSectorId;
private UUID emissionSourceId;
diff --git a/sge-backend/src/main/resources/application.properties b/sge-backend/src/main/resources/application.properties
index 32c28b9..c5132b2 100644
--- a/sge-backend/src/main/resources/application.properties
+++ b/sge-backend/src/main/resources/application.properties
@@ -17,20 +17,14 @@ 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
spring.rabbitmq.template.retry.max-attempts=3
spring.rabbitmq.template.retry.initial-interval=1000ms
-logging.level.org.springframework.amqp=DEBUG
+logging.level.org.springframework.amqp=DEBUG
\ No newline at end of file
diff --git a/sge-frontend/src/navigation/horizontal/index.js b/sge-frontend/src/navigation/horizontal/index.js
index 04271b6..af8d687 100644
--- a/sge-frontend/src/navigation/horizontal/index.js
+++ b/sge-frontend/src/navigation/horizontal/index.js
@@ -49,9 +49,9 @@ export default [
permissionCheck("paginate_roles_get")) && [
{
id: "Organizations",
- title: "DataCenters.title",
+ title: "Data Center Management",
icon: ,
- 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: ,
- navLink: "/verimerkezi",
+ navLink: "/veri-merkezi-genel",
+ },
+ {
+ id: "Areas",
+ title: "Areas.areas",
+ icon: ,
+ 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: ,
+ navLink: "/alanlar",
+ display: permissionCheck("paginate_areas_get") ? "" : "none",
+ },
+ {
+ id: "Countries",
+ title: "Areas.countries",
+ icon: ,
+ navLink: "/ulkeler",
+ display: permissionCheck("paginate_countries_get") ? "" : "none",
+ },
+ {
+ id: "Cities",
+ title: "Areas.cities",
+ icon: ,
+ navLink: "/iller",
+ display: permissionCheck("paginate_cities_get") ? "" : "none",
+ },
+ {
+ id: "Districts",
+ title: "Areas.districts",
+ icon: ,
+ navLink: "/ilceler",
+ display: permissionCheck("paginate_districts_get") ? "" : "none",
+ },
+ {
+ id: "Neighborhoods",
+ title: "Areas.neighborhoods",
+ icon: ,
+ navLink: "/mahalleler",
+ display: permissionCheck("paginate_neighborhoods_get") ? "" : "none",
+ },
+ ],
},
{
id: "Survey",
diff --git a/sge-frontend/src/navigation/vertical/index.js b/sge-frontend/src/navigation/vertical/index.js
index fe24dbf..f3eb6cc 100644
--- a/sge-frontend/src/navigation/vertical/index.js
+++ b/sge-frontend/src/navigation/vertical/index.js
@@ -49,9 +49,9 @@ export default [
permissionCheck("paginate_roles_get")) && [
{
id: "DataCenters",
- title: "DataCenters.title",
+ title: "Data Center Management",
icon: ,
- 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: ,
- navLink: "/verimerkezi",
+ navLink: "/veri-merkezi-genel",
+ },
+ {
+ id: "Areas",
+ title: "Areas.areas",
+ icon: ,
+ 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: ,
+ navLink: "/alanlar",
+ display: permissionCheck("paginate_areas_get") ? "" : "none",
+ },
+ {
+ id: "Countries",
+ title: "Areas.countries",
+ icon: ,
+ navLink: "/ulkeler",
+ display: permissionCheck("paginate_countries_get") ? "" : "none",
+ },
+ {
+ id: "Cities",
+ title: "Areas.cities",
+ icon: ,
+ navLink: "/iller",
+ display: permissionCheck("paginate_cities_get") ? "" : "none",
+ },
+ {
+ id: "Districts",
+ title: "Areas.districts",
+ icon: ,
+ navLink: "/ilceler",
+ display: permissionCheck("paginate_districts_get") ? "" : "none",
+ },
+ {
+ id: "Neighborhoods",
+ title: "Areas.neighborhoods",
+ icon: ,
+ navLink: "/mahalleler",
+ display: permissionCheck("paginate_neighborhoods_get") ? "" : "none",
+ },
+ ],
},
{
id: "Survey",
diff --git a/sge-frontend/src/redux/actions/areas/index.js b/sge-frontend/src/redux/actions/areas/index.js
index 0dd1892..520088c 100644
--- a/sge-frontend/src/redux/actions/areas/index.js
+++ b/sge-frontend/src/redux/actions/areas/index.js
@@ -12,6 +12,15 @@ export const getAreas = () => {
id
tag
isDeleted
+ cities {
+ id
+ name
+ coordinates
+ country {
+ id
+ name
+ }
+ }
}
}
`,
diff --git a/sge-frontend/src/redux/actions/dataCenter/index.js b/sge-frontend/src/redux/actions/dataCenter/index.js
index 8adf43a..e439d5e 100644
--- a/sge-frontend/src/redux/actions/dataCenter/index.js
+++ b/sge-frontend/src/redux/actions/dataCenter/index.js
@@ -34,10 +34,41 @@ export const getDataCenters = () => {
latitude
longitude
area {
+ id
+ tag
+ cities {
+ id
+ name
+ }
+ districts {
+ id
+ name
+ }
+ }
+ emissionScope {
+ id
+ tag
+ description
+ }
+ sector {
+ id
+ tag
+ }
+ subSector {
+ id
+ tag
+ }
+ emissionSource {
+ id
+ tag
+ }
+ consuptionUnit {
+ id
+ description
+ }
+ activitySubUnit {
+ id
tag
- name
- cityId
- districtId
}
projects {
id
@@ -45,12 +76,16 @@ export const getDataCenters = () => {
physicalMachines {
id
name
- vms {
- active {
+ vms {
id
- status
- name
+ vmName
+ state
power
+ calcOn
+ hostingPm
+ host
+ flavorName
+ tag
config {
id
cpu
@@ -58,7 +93,6 @@ export const getDataCenters = () => {
disk
}
}
- }
}
}
}
@@ -155,10 +189,41 @@ export const createDataCenter = (dataCenterData) => {
latitude
longitude
area {
+ id
+ tag
+ cities {
+ id
+ name
+ }
+ districts {
+ id
+ name
+ }
+ }
+ emissionScope {
+ id
+ tag
+ description
+ }
+ sector {
+ id
+ tag
+ }
+ subSector {
+ id
+ tag
+ }
+ emissionSource {
+ id
+ tag
+ }
+ consuptionUnit {
+ id
+ description
+ }
+ activitySubUnit {
+ id
tag
- name
- cityId
- districtId
}
}
}
@@ -169,11 +234,16 @@ export const createDataCenter = (dataCenterData) => {
externalId: parseInt(dataCenterData.externalId),
ayposURL: dataCenterData.ayposURL || "",
number: parseInt(dataCenterData.number) || 1,
- areaId: dataCenterData.areaId,
+ areaId: dataCenterData.areaId || null,
address: dataCenterData.address || "",
latitude: dataCenterData.latitude ? parseFloat(dataCenterData.latitude) : null,
longitude: dataCenterData.longitude ? parseFloat(dataCenterData.longitude) : null,
- city: dataCenterData.city
+ emissionScopeId: dataCenterData.emissionScopeId || null,
+ sectorId: dataCenterData.sectorId || null,
+ subSectorId: dataCenterData.subSectorId || null,
+ emissionSourceId: dataCenterData.emissionSourceId || null,
+ consuptionUnitId: dataCenterData.consuptionUnitId || null,
+ activitySubUnitId: dataCenterData.activitySubUnitId || null
}
}
},
@@ -240,10 +310,41 @@ export const updateDataCenter = (id, dataCenterData) => {
latitude
longitude
area {
+ id
+ tag
+ cities {
+ id
+ name
+ }
+ districts {
+ id
+ name
+ }
+ }
+ emissionScope {
+ id
+ tag
+ description
+ }
+ sector {
+ id
+ tag
+ }
+ subSector {
+ id
+ tag
+ }
+ emissionSource {
+ id
+ tag
+ }
+ consuptionUnit {
+ id
+ description
+ }
+ activitySubUnit {
+ id
tag
- name
- cityId
- districtId
}
}
}
@@ -255,11 +356,16 @@ export const updateDataCenter = (id, dataCenterData) => {
externalId: parseInt(dataCenterData.externalId),
ayposURL: dataCenterData.ayposURL || "",
number: parseInt(dataCenterData.number) || 1,
- areaId: dataCenterData.areaId,
+ areaId: dataCenterData.areaId || null,
address: dataCenterData.address || "",
latitude: dataCenterData.latitude ? parseFloat(dataCenterData.latitude) : null,
longitude: dataCenterData.longitude ? parseFloat(dataCenterData.longitude) : null,
- city: dataCenterData.city
+ emissionScopeId: dataCenterData.emissionScopeId || null,
+ sectorId: dataCenterData.sectorId || null,
+ subSectorId: dataCenterData.subSectorId || null,
+ emissionSourceId: dataCenterData.emissionSourceId || null,
+ consuptionUnitId: dataCenterData.consuptionUnitId || null,
+ activitySubUnitId: dataCenterData.activitySubUnitId || null
}
}
},
@@ -342,6 +448,56 @@ 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
diff --git a/sge-frontend/src/redux/actions/mainDataTables/index.js b/sge-frontend/src/redux/actions/mainDataTables/index.js
index 77c70a9..0db497f 100644
--- a/sge-frontend/src/redux/actions/mainDataTables/index.js
+++ b/sge-frontend/src/redux/actions/mainDataTables/index.js
@@ -125,11 +125,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 +139,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
diff --git a/sge-frontend/src/redux/reducers/emissionScope/index.js b/sge-frontend/src/redux/reducers/emissionScope/index.js
new file mode 100644
index 0000000..19cd08b
--- /dev/null
+++ b/sge-frontend/src/redux/reducers/emissionScope/index.js
@@ -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;
\ No newline at end of file
diff --git a/sge-frontend/src/redux/reducers/rootReducer.js b/sge-frontend/src/redux/reducers/rootReducer.js
index 1d201a5..696a0a9 100644
--- a/sge-frontend/src/redux/reducers/rootReducer.js
+++ b/sge-frontend/src/redux/reducers/rootReducer.js
@@ -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;
diff --git a/sge-frontend/src/router/routes/index.js b/sge-frontend/src/router/routes/index.js
index 9ce00a0..a25bdfe 100644
--- a/sge-frontend/src/router/routes/index.js
+++ b/sge-frontend/src/router/routes/index.js
@@ -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")),
},
{
diff --git a/sge-frontend/src/views/DataCenter.js b/sge-frontend/src/views/DataCenter.js
index e4599a0..b1b9d60 100644
--- a/sge-frontend/src/views/DataCenter.js
+++ b/sge-frontend/src/views/DataCenter.js
@@ -41,14 +41,23 @@ const DataCenter = () => {
// Projects
{
name: "Projects",
- selector: (row) =>
- (row.projects || []).map((p) => p.name).join(", "),
- sortable: false,
+ selector: (row) => (row.projects || []).length,
+ sortable: true,
minWidth: "200px",
cell: (row) => (
-
- {(row.projects || []).map((p) => p.name).join(", ") || "-"}
-
+
+ {(row.projects || []).length > 0 ? (
+
+ {row.projects.map((project, index) => (
+
0 ? 'mt-1' : ''}`}>
+ {project.name}
+
+ ))}
+
+ ) : (
+
-
+ )}
+
),
},
// Physical Machines
@@ -68,26 +77,41 @@ 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 (
-
-
{totalVMs}
+
+
+
{vms.total} Total
+
+ {vms.active} Active
+ •
+ {vms.total - vms.active} Inactive
+
+
);
},
@@ -138,76 +162,78 @@ const DataCenter = () => {
{pm.name}
- {/* Active VMs */}
-
- Active VMs ({pm.vms?.active?.length || 0}):
-
- {pm.vms?.active?.length > 0 ? (
-
- {pm.vms.active.map((vm) => (
-
-
-
- Name: {vm.name}
-
-
- Status:
-
- {vm.status}
-
-
-
- Power: {vm.power}
-
-
- Config: CPU: {vm.config?.cpu}, RAM:{" "}
- {vm.config?.ram}, Disk: {vm.config?.disk}
-
-
-
- ))}
+ {/* All VMs */}
+
+
+
+ Virtual Machines ({pm.vms?.length || 0})
+
+
+ {pm.vms?.length > 0 ? (
+
+
+
+
+ | Name |
+ Status |
+ Power (W) |
+ Configuration |
+ Host |
+
+
+
+ {pm.vms.map((vm) => {
+ const isActive = vm.state && ["ACTIVE", "active"].includes(vm.state);
+ return (
+
+ |
+ {vm.vmName || vm.vm_name}
+ |
+
+
+ {vm.state}
+
+ |
+
+ {vm.power ? (
+ {vm.power.toFixed(2)}
+ ) : (
+ -
+ )}
+ |
+
+
+
+ CPU
+ {(vm.config?.cpu || (vm.confg && vm.confg[1])) || '-'}
+
+
+ RAM
+ {(vm.config?.ram || (vm.confg && vm.confg[2])) || '-'} GB
+
+
+ Disk
+ {(vm.config?.disk || (vm.confg && vm.confg[3])) || '-'} GB
+
+
+ |
+
+
+
+ {vm.host || vm.hostingPm || (vm.confg && vm.confg[4]) || '-'}
+
+ |
+
+ );
+ })}
+
+
) : (
-
No active VMs
- )}
-
- {/* Inactive VMs */}
-
- Inactive VMs ({pm.vms?.inactive?.length || 0}):
-
- {pm.vms?.inactive?.length > 0 ? (
-
- {pm.vms.inactive.map((vm) => (
-
-
-
- Name: {vm.name}
-
-
- Status:
-
- {vm.status}
-
-
-
- Power: {vm.power}
-
-
- Config: CPU: {vm.config?.cpu}, RAM:{" "}
- {vm.config?.ram}, Disk: {vm.config?.disk}
-
-
-
- ))}
+
+
+
No virtual machines found
- ) : (
-
No inactive VMs
)}
))}
diff --git a/sge-frontend/src/views/DataCenterManagement.js b/sge-frontend/src/views/DataCenterManagement.js
index c344df6..d77f7df 100644
--- a/sge-frontend/src/views/DataCenterManagement.js
+++ b/sge-frontend/src/views/DataCenterManagement.js
@@ -28,7 +28,8 @@ import { Edit } from "@mui/icons-material";
import { useSnackbar } from "notistack";
import { default as SweetAlert } from "sweetalert2";
import withReactContent from "sweetalert2-react-content";
-import { getDataCenters, createDataCenter, updateDataCenter, deleteDataCenter } from "../redux/actions/dataCenter";
+import { getDataCenters, createDataCenter, updateDataCenter, deleteDataCenter, getEmissionScopes } from "../redux/actions/dataCenter";
+import { getAreas, getAreasWithCriteria } from "../redux/actions/areas";
import { useTranslation } from "react-i18next";
import { getSectors, getSectorById, getSubSectorById, getConsuptionUnits } from "../redux/actions/datas";
import { getAllEmissionSources } from "../redux/actions/emissionSources";
@@ -105,6 +106,8 @@ const DataCenterManagement = () => {
externalId: "",
number: "",
address: "",
+ areaId: null,
+ cityId: null,
latitude: null,
longitude: null,
ayposURL: "",
@@ -120,14 +123,18 @@ const DataCenterManagement = () => {
const [mapPosition, setMapPosition] = useState(null);
const dataCenterStore = useSelector((state) => state.dataCenter);
+ const emissionScopeStore = useSelector((state) => state.emissionScope);
const datasStore = useSelector((state) => state.datas);
const emissionSourceStore = useSelector((state) => state.emissionSources);
+ const areasStore = useSelector((state) => state.areas);
const [sectorsOptions, setSectorsOptions] = useState([]);
const [subSectorsOptions, setSubSectorsOptions] = useState([]);
const [emissionSourcesOptions, setEmissionSourcesOptions] = useState([]);
const [consuptionUnitsOptions, setConsuptionUnitsOptions] = useState([]);
const [activitySubUnitsOptions, setActivitySubUnitsOptions] = useState([]);
const [emissionScopesOptions, setEmissionScopesOptions] = useState([]);
+ const [areasOptions, setAreasOptions] = useState([]);
+ const [citiesOptions, setCitiesOptions] = useState([]);
// Add state for selected sector and sub sector like in data input
const [selectedSector, setSelectedSector] = useState(null);
@@ -215,6 +222,8 @@ const DataCenterManagement = () => {
useEffect(() => {
dispatch(getDataCenters());
dispatch(getSectors());
+ dispatch(getAreas());
+ dispatch(getEmissionScopes());
}, [dispatch]);
useEffect(() => {
@@ -295,17 +304,48 @@ const DataCenterManagement = () => {
}, [datasStore?.consuptionUnits]);
useEffect(() => {
- setEmissionScopesOptions([
- {
- label: "Şehir İçi",
- value: false,
- },
- {
- label: "Şehir Dışı",
- value: true,
- },
- ]);
- }, []);
+ if (emissionScopeStore?.emissionScopes) {
+ setEmissionScopesOptions(
+ emissionScopeStore.emissionScopes.map((scope) => ({
+ value: scope.id,
+ label: scope.tag,
+ }))
+ );
+ }
+ }, [emissionScopeStore?.emissionScopes]);
+
+ // Set areas options when areas data is loaded
+ useEffect(() => {
+ if (areasStore?.areas) {
+ setAreasOptions(
+ areasStore.areas.map((area) => ({
+ value: area.id,
+ label: area.tag,
+ }))
+ );
+ }
+ }, [areasStore?.areas]);
+
+ // Set cities options when selected area changes
+ useEffect(() => {
+ if (selectedDataCenter.areaId && areasStore?.areas) {
+ const selectedArea = areasStore.areas.find(
+ (area) => area.id === selectedDataCenter.areaId
+ );
+ if (selectedArea?.cities) {
+ setCitiesOptions(
+ selectedArea.cities.map((city) => ({
+ value: city.id,
+ label: city.name,
+ }))
+ );
+ } else {
+ setCitiesOptions([]);
+ }
+ } else {
+ setCitiesOptions([]);
+ }
+ }, [selectedDataCenter.areaId, areasStore?.areas]);
const handleEditDataCenter = (row) => {
setEditingDataCenter(row);
@@ -314,10 +354,12 @@ const DataCenterManagement = () => {
externalId: row.externalId,
number: row.number,
address: row.address,
+ areaId: row.area?.id,
+ cityId: null, // City is a string in the backend, not an object
latitude: row.latitude,
longitude: row.longitude,
ayposURL: row.ayposURL,
- city: row.city,
+ city: row.city || "",
emissionScopeId: row.emissionScope?.id,
sectorId: row.sector?.id,
subSectorId: row.subSector?.id,
@@ -364,9 +406,56 @@ const DataCenterManagement = () => {
}
};
+ const validateForm = () => {
+ const errors = [];
+
+ // Required fields
+ if (!selectedDataCenter.name) {
+ errors.push(t("DataCenter.nameRequired"));
+ }
+ if (!selectedDataCenter.externalId) {
+ errors.push(t("DataCenter.externalIdRequired"));
+ }
+ if (!selectedDataCenter.sectorId) {
+ errors.push(t("DataCenter.sectorRequired"));
+ }
+
+ // Validate external ID is a number
+ if (selectedDataCenter.externalId && isNaN(parseInt(selectedDataCenter.externalId))) {
+ errors.push(t("DataCenter.externalIdMustBeNumber"));
+ }
+
+ // Validate coordinates if either is provided
+ if ((selectedDataCenter.latitude && !selectedDataCenter.longitude) ||
+ (!selectedDataCenter.latitude && selectedDataCenter.longitude)) {
+ errors.push(t("DataCenter.bothCoordinatesRequired"));
+ }
+
+ // Validate area and city are selected together
+ if (selectedDataCenter.areaId && !selectedDataCenter.cityId) {
+ errors.push(t("DataCenter.cityRequired"));
+ }
+
+ // Validate sector hierarchy
+ if (selectedDataCenter.subSectorId && !selectedDataCenter.sectorId) {
+ errors.push(t("DataCenter.sectorRequired"));
+ }
+ if (selectedDataCenter.emissionSourceId && !selectedDataCenter.subSectorId) {
+ errors.push(t("DataCenter.subSectorRequired"));
+ }
+ if (selectedDataCenter.consuptionUnitId && !selectedDataCenter.emissionSourceId) {
+ errors.push(t("DataCenter.emissionSourceRequired"));
+ }
+
+ return errors;
+ };
+
const handleSubmit = async () => {
- if (!selectedDataCenter.name || !selectedDataCenter.externalId) {
- enqueueSnackbar(t("Common.fillRequiredFields"), { variant: "error" });
+ const validationErrors = validateForm();
+ if (validationErrors.length > 0) {
+ validationErrors.forEach(error => {
+ enqueueSnackbar(error, { variant: "error" });
+ });
return;
}
@@ -397,10 +486,20 @@ const DataCenterManagement = () => {
handleCloseModal();
} catch (error) {
console.error("Submit error:", error);
- enqueueSnackbar(
- error?.message || t("DataCenter.submitError"),
- { variant: "error" }
- );
+
+ // Handle specific error cases
+ if (error.message?.includes("duplicate")) {
+ enqueueSnackbar(t("DataCenter.duplicateExternalId"), { variant: "error" });
+ } else if (error.message?.includes("permission")) {
+ enqueueSnackbar(t("Common.noPermission"), { variant: "error" });
+ } else if (error.message?.includes("not found")) {
+ enqueueSnackbar(t("DataCenter.resourceNotFound"), { variant: "error" });
+ } else {
+ enqueueSnackbar(
+ error?.message || t("DataCenter.submitError"),
+ { variant: "error" }
+ );
+ }
}
};
@@ -599,19 +698,49 @@ const DataCenterManagement = () => {
-
-
+
+
+
+
+
+
+
@@ -670,7 +799,7 @@ const DataCenterManagement = () => {
-
+