From d730a588234f0ab70ae3a786a25cc6bf9d7a984d Mon Sep 17 00:00:00 2001 From: The-Coding-Kiddo Date: Sun, 27 Jul 2025 21:10:01 +0300 Subject: [PATCH] city, graphics page, errors on graphics still --- .../graphql/dataCenter/domain/DataCenter.java | 9 + .../graphql/dataCenter/dto/DataCenterDto.java | 8 + .../mutation/DataCenterMutation.java | 121 +- .../mutation/input/DataCenterInput.java | 72 + .../repo/criteria/MainDataTableCriteria.java | 9 + .../spec/MainDataTableCriteriaSpec.java | 7 +- .../graphql/dataCenter/type.graphqls | 8 + .../graphql/mainDataTable/criteria.graphqls | 1 + .../graphql/mainDataTable/type.graphqls | 18 +- sge-frontend/src/redux/actions/areas/index.js | 111 + .../src/redux/actions/dataCenter/index.js | 90 +- sge-frontend/src/redux/actions/datas/index.js | 2 +- .../src/redux/actions/mainDataTables/index.js | 116 + .../src/redux/reducers/datas/index.js | 2 +- .../src/views/DataCenterManagement.js | 322 ++- sge-frontend/src/views/Graphics.js | 2044 +++++++++-------- 16 files changed, 1888 insertions(+), 1052 deletions(-) diff --git a/sge-backend/src/main/java/com/sgs/graphql/dataCenter/domain/DataCenter.java b/sge-backend/src/main/java/com/sgs/graphql/dataCenter/domain/DataCenter.java index 6f19514..7f13c72 100644 --- a/sge-backend/src/main/java/com/sgs/graphql/dataCenter/domain/DataCenter.java +++ b/sge-backend/src/main/java/com/sgs/graphql/dataCenter/domain/DataCenter.java @@ -33,6 +33,7 @@ public class DataCenter extends BaseDomain { private Double latitude; private Double longitude; private Area area; + private String city; private List projects = new ArrayList<>(); private Sector sector; @@ -201,4 +202,12 @@ public class DataCenter extends BaseDomain { public void setActivitySubUnit(ActivitySubUnit activitySubUnit) { this.activitySubUnit = activitySubUnit; } + + @Column(name = "city") + public String getCity() { + return city; + } + public void setCity(String city) { + this.city = city; + } } \ No newline at end of file diff --git a/sge-backend/src/main/java/com/sgs/graphql/dataCenter/dto/DataCenterDto.java b/sge-backend/src/main/java/com/sgs/graphql/dataCenter/dto/DataCenterDto.java index b77cd96..cdb3913 100644 --- a/sge-backend/src/main/java/com/sgs/graphql/dataCenter/dto/DataCenterDto.java +++ b/sge-backend/src/main/java/com/sgs/graphql/dataCenter/dto/DataCenterDto.java @@ -16,6 +16,7 @@ public class DataCenterDto { private int id; private Integer externalId; private Integer number; + private String city; private AreaDto area; private List projects; @@ -61,6 +62,13 @@ public class DataCenterDto { this.number = number; } + public String getCity() { + return city; + } + public void setCity(String city) { + this.city = city; + } + public AreaDto getArea() { return area; } diff --git a/sge-backend/src/main/java/com/sgs/graphql/dataCenter/mutation/DataCenterMutation.java b/sge-backend/src/main/java/com/sgs/graphql/dataCenter/mutation/DataCenterMutation.java index a00bce2..4562aca 100644 --- a/sge-backend/src/main/java/com/sgs/graphql/dataCenter/mutation/DataCenterMutation.java +++ b/sge-backend/src/main/java/com/sgs/graphql/dataCenter/mutation/DataCenterMutation.java @@ -11,6 +11,18 @@ import com.sgs.graphql.userHistory.mutation.UserLogger; import com.sgs.graphql.userNotification.mutation.UserNotificationMutation; import com.sgs.graphql.area.domain.Area; import com.sgs.graphql.area.service.AreaService; +import com.sgs.graphql.emissionScope.domain.EmissionScope; +import com.sgs.graphql.emissionScope.service.EmissionScopeService; +import com.sgs.graphql.sector.domain.Sector; +import com.sgs.graphql.sector.service.SectorService; +import com.sgs.graphql.subSector.domain.SubSector; +import com.sgs.graphql.subSector.service.SubSectorService; +import com.sgs.graphql.emissionSource.domain.EmissionSource; +import com.sgs.graphql.emissionSource.service.EmissionSourceService; +import com.sgs.graphql.consuptionUnit.domain.ConsuptionUnit; +import com.sgs.graphql.consuptionUnit.service.ConsuptionUnitService; +import com.sgs.graphql.activitySubUnit.domain.ActivitySubUnit; +import com.sgs.graphql.activitySubUnit.service.ActivitySubUnitService; import graphql.kickstart.tools.GraphQLMutationResolver; import graphql.schema.DataFetchingEnvironment; import org.springframework.beans.factory.annotation.Autowired; @@ -27,17 +39,32 @@ public class DataCenterMutation implements GraphQLMutationResolver { private final DataCenterService dataCenterService; private final DataCenterRepo dataCenterRepo; private final AreaService areaService; + private final EmissionScopeService emissionScopeService; + private final SectorService sectorService; + private final SubSectorService subSectorService; + private final EmissionSourceService emissionSourceService; + private final ConsuptionUnitService consuptionUnitService; + private final ActivitySubUnitService activitySubUnitService; private final SystemLogger systemLogger; private final UserLogger userLogger; private final UserNotificationMutation notificationMutation; @Autowired public DataCenterMutation(DataCenterService dataCenterService, DataCenterRepo dataCenterRepo, - AreaService areaService, SystemLogger systemLogger, + AreaService areaService, EmissionScopeService emissionScopeService, + SectorService sectorService, SubSectorService subSectorService, + EmissionSourceService emissionSourceService, ConsuptionUnitService consuptionUnitService, + ActivitySubUnitService activitySubUnitService, SystemLogger systemLogger, UserLogger userLogger, UserNotificationMutation notificationMutation) { this.dataCenterService = dataCenterService; this.dataCenterRepo = dataCenterRepo; this.areaService = areaService; + this.emissionScopeService = emissionScopeService; + this.sectorService = sectorService; + this.subSectorService = subSectorService; + this.emissionSourceService = emissionSourceService; + this.consuptionUnitService = consuptionUnitService; + this.activitySubUnitService = activitySubUnitService; this.systemLogger = systemLogger; this.userLogger = userLogger; this.notificationMutation = notificationMutation; @@ -57,6 +84,8 @@ public class DataCenterMutation implements GraphQLMutationResolver { dataCenter.setAddress(input.getAddress()); dataCenter.setLatitude(input.getLatitude()); dataCenter.setLongitude(input.getLongitude()); + dataCenter.setCity(input.getCity()); + dataCenter.setConsuptionAmount(input.getConsuptionAmount()); // Set area if provided if (input.getAreaId() != null) { @@ -65,6 +94,48 @@ public class DataCenterMutation implements GraphQLMutationResolver { dataCenter.setArea(area); } + // Set emission scope if provided + if (input.getEmissionScopeId() != null) { + EmissionScope emissionScope = emissionScopeService.findById(input.getEmissionScopeId()) + .orElseThrow(() -> new NoSuchElementException("Emission scope not found with id: " + input.getEmissionScopeId())); + dataCenter.setEmissionScope(emissionScope); + } + + // Set sector if provided + if (input.getSectorId() != null) { + Sector sector = sectorService.findById(input.getSectorId()) + .orElseThrow(() -> new NoSuchElementException("Sector not found with id: " + input.getSectorId())); + dataCenter.setSector(sector); + } + + // Set sub sector if provided + if (input.getSubSectorId() != null) { + SubSector subSector = subSectorService.findById(input.getSubSectorId()) + .orElseThrow(() -> new NoSuchElementException("Sub sector not found with id: " + input.getSubSectorId())); + dataCenter.setSubSector(subSector); + } + + // Set emission source if provided + if (input.getEmissionSourceId() != null) { + EmissionSource emissionSource = emissionSourceService.findById(input.getEmissionSourceId()) + .orElseThrow(() -> new NoSuchElementException("Emission source not found with id: " + input.getEmissionSourceId())); + dataCenter.setEmissionSource(emissionSource); + } + + // Set consumption unit if provided + if (input.getConsuptionUnitId() != null) { + ConsuptionUnit consuptionUnit = consuptionUnitService.findById(input.getConsuptionUnitId()) + .orElseThrow(() -> new NoSuchElementException("Consumption unit not found with id: " + input.getConsuptionUnitId())); + dataCenter.setConsuptionUnit(consuptionUnit); + } + + // Set activity sub unit if provided + if (input.getActivitySubUnitId() != null) { + ActivitySubUnit activitySubUnit = activitySubUnitService.findById(input.getActivitySubUnitId()) + .orElseThrow(() -> new NoSuchElementException("Activity sub unit not found with id: " + input.getActivitySubUnitId())); + dataCenter.setActivitySubUnit(activitySubUnit); + } + // Set number if not provided if (dataCenter.getNumber() == null) { Integer maxNumber = dataCenterRepo.findMaxNumber(); @@ -121,6 +192,12 @@ public class DataCenterMutation implements GraphQLMutationResolver { if (input.getLongitude() != null) { dataCenter.setLongitude(input.getLongitude()); } + if (input.getCity() != null) { + dataCenter.setCity(input.getCity()); + } + if (input.getConsuptionAmount() != null) { + dataCenter.setConsuptionAmount(input.getConsuptionAmount()); + } // Update area if provided if (input.getAreaId() != null) { @@ -129,6 +206,48 @@ public class DataCenterMutation implements GraphQLMutationResolver { dataCenter.setArea(area); } + // Update emission scope if provided + if (input.getEmissionScopeId() != null) { + EmissionScope emissionScope = emissionScopeService.findById(input.getEmissionScopeId()) + .orElseThrow(() -> new NoSuchElementException("Emission scope not found with id: " + input.getEmissionScopeId())); + dataCenter.setEmissionScope(emissionScope); + } + + // Update sector if provided + if (input.getSectorId() != null) { + Sector sector = sectorService.findById(input.getSectorId()) + .orElseThrow(() -> new NoSuchElementException("Sector not found with id: " + input.getSectorId())); + dataCenter.setSector(sector); + } + + // Update sub sector if provided + if (input.getSubSectorId() != null) { + SubSector subSector = subSectorService.findById(input.getSubSectorId()) + .orElseThrow(() -> new NoSuchElementException("Sub sector not found with id: " + input.getSubSectorId())); + dataCenter.setSubSector(subSector); + } + + // Update emission source if provided + if (input.getEmissionSourceId() != null) { + EmissionSource emissionSource = emissionSourceService.findById(input.getEmissionSourceId()) + .orElseThrow(() -> new NoSuchElementException("Emission source not found with id: " + input.getEmissionSourceId())); + dataCenter.setEmissionSource(emissionSource); + } + + // Update consumption unit if provided + if (input.getConsuptionUnitId() != null) { + ConsuptionUnit consuptionUnit = consuptionUnitService.findById(input.getConsuptionUnitId()) + .orElseThrow(() -> new NoSuchElementException("Consumption unit not found with id: " + input.getConsuptionUnitId())); + dataCenter.setConsuptionUnit(consuptionUnit); + } + + // Update activity sub unit if provided + if (input.getActivitySubUnitId() != null) { + ActivitySubUnit activitySubUnit = activitySubUnitService.findById(input.getActivitySubUnitId()) + .orElseThrow(() -> new NoSuchElementException("Activity sub unit not found with id: " + input.getActivitySubUnitId())); + dataCenter.setActivitySubUnit(activitySubUnit); + } + // Save the updated data center DataCenter updatedDataCenter = dataCenterService.save(dataCenter); diff --git a/sge-backend/src/main/java/com/sgs/graphql/dataCenter/mutation/input/DataCenterInput.java b/sge-backend/src/main/java/com/sgs/graphql/dataCenter/mutation/input/DataCenterInput.java index 60fcb75..0da3007 100644 --- a/sge-backend/src/main/java/com/sgs/graphql/dataCenter/mutation/input/DataCenterInput.java +++ b/sge-backend/src/main/java/com/sgs/graphql/dataCenter/mutation/input/DataCenterInput.java @@ -13,6 +13,14 @@ public class DataCenterInput extends BaseCreateInput { private Double latitude; private Double longitude; private UUID areaId; + private String city; + private UUID emissionScopeId; + private UUID sectorId; + private UUID subSectorId; + private UUID emissionSourceId; + private UUID consuptionUnitId; + private Double consuptionAmount; + private UUID activitySubUnitId; public String getDataCenter() { return dataCenter; @@ -77,5 +85,69 @@ public class DataCenterInput extends BaseCreateInput { public void setAreaId(UUID areaId) { this.areaId = areaId; } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public UUID getEmissionScopeId() { + return emissionScopeId; + } + + public void setEmissionScopeId(UUID emissionScopeId) { + this.emissionScopeId = emissionScopeId; + } + + public UUID getSectorId() { + return sectorId; + } + + public void setSectorId(UUID sectorId) { + this.sectorId = sectorId; + } + + public UUID getSubSectorId() { + return subSectorId; + } + + public void setSubSectorId(UUID subSectorId) { + this.subSectorId = subSectorId; + } + + public UUID getEmissionSourceId() { + return emissionSourceId; + } + + public void setEmissionSourceId(UUID emissionSourceId) { + this.emissionSourceId = emissionSourceId; + } + + public UUID getConsuptionUnitId() { + return consuptionUnitId; + } + + public void setConsuptionUnitId(UUID consuptionUnitId) { + this.consuptionUnitId = consuptionUnitId; + } + + public Double getConsuptionAmount() { + return consuptionAmount; + } + + public void setConsuptionAmount(Double consuptionAmount) { + this.consuptionAmount = consuptionAmount; + } + + public UUID getActivitySubUnitId() { + return activitySubUnitId; + } + + public void setActivitySubUnitId(UUID activitySubUnitId) { + this.activitySubUnitId = activitySubUnitId; + } } diff --git a/sge-backend/src/main/java/com/sgs/graphql/mainDataTable/repo/criteria/MainDataTableCriteria.java b/sge-backend/src/main/java/com/sgs/graphql/mainDataTable/repo/criteria/MainDataTableCriteria.java index 87a21ed..d305502 100644 --- a/sge-backend/src/main/java/com/sgs/graphql/mainDataTable/repo/criteria/MainDataTableCriteria.java +++ b/sge-backend/src/main/java/com/sgs/graphql/mainDataTable/repo/criteria/MainDataTableCriteria.java @@ -12,6 +12,7 @@ public class MainDataTableCriteria extends BaseCriteria { private UUID neighborhood; private UUID organization; private String year; + private UUID vm; public UUID getSector() { return sector; @@ -68,4 +69,12 @@ public class MainDataTableCriteria extends BaseCriteria { public void setYear(String year) { this.year = year; } + + public UUID getVm() { + return vm; + } + + public void setVm(UUID vm) { + this.vm = vm; + } } diff --git a/sge-backend/src/main/java/com/sgs/graphql/mainDataTable/repo/criteria/spec/MainDataTableCriteriaSpec.java b/sge-backend/src/main/java/com/sgs/graphql/mainDataTable/repo/criteria/spec/MainDataTableCriteriaSpec.java index 4156fc5..b529325 100644 --- a/sge-backend/src/main/java/com/sgs/graphql/mainDataTable/repo/criteria/spec/MainDataTableCriteriaSpec.java +++ b/sge-backend/src/main/java/com/sgs/graphql/mainDataTable/repo/criteria/spec/MainDataTableCriteriaSpec.java @@ -38,6 +38,10 @@ public class MainDataTableCriteriaSpec extends BaseCriteriaSpec) (root, query, criteriaBuilder) -> criteriaBuilder.equal(root.get("year"), year); } + public static Specification vm(UUID vm) { + return (vm == null) ? null : (Specification) (root, query, criteriaBuilder) -> criteriaBuilder.equal(root.join("vm").get("id"), vm); + } + @Override public Specification createForAll(MainDataTableCriteria criteria) { return Specification.where(sector(criteria.getSector())) @@ -45,6 +49,7 @@ public class MainDataTableCriteriaSpec extends BaseCriteriaSpec { }; }; +export const getAreasByDataCenter = (dataCenterId) => { + return async (dispatch) => { + // Don't make the request if dataCenterId is undefined, null, or empty + if (!dataCenterId || dataCenterId === "undefined") { + dispatch({ + type: "GET_AREAS_WITH_CRITERIA", + payload: { + getAreasWithCriteria: [], + }, + }); + return; + } + + ApplicationService.http() + .post( + "/graphql", + { + query: ` + { + dataCenter(id: "${dataCenterId}") { + id + dataCenter + area { + id + tag + countries { + id + countryCode + name + } + cities { + id + name + coordinates + country{ + id + name + } + } + districts { + id + name + coordinates + city{ + id + name + country{ + id + name + } + } + } + neighborhoods { + id + name + minLong + maxLong + minLat + maxLat + district{ + id + name + city{ + id + name + country{ + id + name + } + } + } + } + isDeleted + } + } + } + `, + }, + { + headers: { + Authorization: "Bearer " + localStorage.getItem("accessToken"), + }, + } + ) + .then((response) => { + const dataCenter = response?.data?.data?.dataCenter; + let areas = []; + + if (dataCenter && dataCenter.area && !dataCenter.area.isDeleted) { + areas = [dataCenter.area]; + } + + dispatch({ + type: "GET_AREAS_WITH_CRITERIA", + payload: { + getAreasWithCriteria: areas, + }, + }); + }) + .catch((error) => { + console.error("Error fetching areas by data center:", error); + dispatch({ + type: "GET_AREAS_WITH_CRITERIA", + payload: { + getAreasWithCriteria: [], + }, + }); + }); + }; +}; + export const addArea = (data) => { const dataToJSON = JSON.stringify(data); const deleteQuotesFromKey = dataToJSON.replace(/"([^(")"]+)":/g, "$1:"); diff --git a/sge-frontend/src/redux/actions/dataCenter/index.js b/sge-frontend/src/redux/actions/dataCenter/index.js index 8ad77a5..941364a 100644 --- a/sge-frontend/src/redux/actions/dataCenter/index.js +++ b/sge-frontend/src/redux/actions/dataCenter/index.js @@ -170,7 +170,8 @@ export const createDataCenter = (dataCenterData) => { areaId: dataCenterData.areaId, address: dataCenterData.address || "", latitude: dataCenterData.latitude ? parseFloat(dataCenterData.latitude) : null, - longitude: dataCenterData.longitude ? parseFloat(dataCenterData.longitude) : null + longitude: dataCenterData.longitude ? parseFloat(dataCenterData.longitude) : null, + city: dataCenterData.city } } }, @@ -254,7 +255,8 @@ export const updateDataCenter = (id, dataCenterData) => { areaId: dataCenterData.areaId, address: dataCenterData.address || "", latitude: dataCenterData.latitude ? parseFloat(dataCenterData.latitude) : null, - longitude: dataCenterData.longitude ? parseFloat(dataCenterData.longitude) : null + longitude: dataCenterData.longitude ? parseFloat(dataCenterData.longitude) : null, + city: dataCenterData.city } } }, @@ -336,3 +338,87 @@ export const deleteDataCenter = (id) => { } }; }; + +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'); + resolve([]); + return; + } + + try { + console.log('getDataCenterVMs: Fetching VMs for data center:', dataCenterId); + const response = await ApplicationService.http() + .post( + "/graphql", + { + query: ` + { + dataCenter(id: "${dataCenterId}") { + id + dataCenter + projects { + id + name + physicalMachines { + id + name + vms { + active { + id + name + status + power + } + inactive { + id + name + status + power + } + } + } + } + } + } + `, + }, + { + headers: { + Authorization: "Bearer " + localStorage.getItem("accessToken"), + }, + } + ); + + const dataCenter = response?.data?.data?.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) { + if (pm.vms.active) { + allVMs = allVMs.concat(pm.vms.active); + } + if (pm.vms.inactive) { + allVMs = allVMs.concat(pm.vms.inactive); + } + } + }); + } + }); + } + + console.log('getDataCenterVMs: Found VMs:', allVMs); + resolve(allVMs); + } catch (error) { + console.error("Error fetching VMs by data center:", error); + resolve([]); + } + }); +}; diff --git a/sge-frontend/src/redux/actions/datas/index.js b/sge-frontend/src/redux/actions/datas/index.js index 04229a9..2649d33 100644 --- a/sge-frontend/src/redux/actions/datas/index.js +++ b/sge-frontend/src/redux/actions/datas/index.js @@ -161,7 +161,7 @@ export const getSubSectorById = (id) => { dispatch({ type: "GET_SUBSECTOR_BY_ID", payload: { - subSector, + subSector: subSector || {}, }, }); }); diff --git a/sge-frontend/src/redux/actions/mainDataTables/index.js b/sge-frontend/src/redux/actions/mainDataTables/index.js index 4fee0f7..77c70a9 100644 --- a/sge-frontend/src/redux/actions/mainDataTables/index.js +++ b/sge-frontend/src/redux/actions/mainDataTables/index.js @@ -689,3 +689,119 @@ export const deleteDataInput = (dataId) => { }); }; }; + +export const getMainDataTablesByVMs = (data) => { + return async (dispatch) => { + const { filterOptions } = data; + try { + const response = await ApplicationService.http() + .post( + "/graphql", + { + query: ` + { + mainDataTables( + criteria: { + year: "${filterOptions?.year?.value}" + deleted: false + } + ) { + year + sector { id tag } + subSector{ id tag } + activitySubUnit{ id tag } + totalEmission + emissionScope{ tag } + emissionSource{ id tag } + vm { id name status power } + } + } + `, + }, + { + headers: { + Authorization: "Bearer " + localStorage.getItem("accessToken"), + }, + } + ); + const allMainDataTables = response.data.data.mainDataTables || []; + dispatch({ + type: "GET_MAIN_TABLES", + payload: { + mainDataTables: allMainDataTables, + }, + }); + } catch (error) { + console.error("Error fetching main data tables:", error); + dispatch({ + type: "GET_MAIN_TABLES", + payload: { + mainDataTables: [], + }, + }); + } + }; +}; + +export const testMainDataTables = () => { + return async (dispatch) => { + try { + console.log('testMainDataTables: Testing basic mainDataTables query'); + + const response = await ApplicationService.http() + .post( + "/graphql", + { + query: ` + { + mainDataTables( + criteria: { + deleted: false + } + ) { + id + year + totalEmission + vm { + id + name + status + power + } + } + } + `, + }, + { + headers: { + Authorization: "Bearer " + localStorage.getItem("accessToken"), + }, + } + ); + + console.log('testMainDataTables: Response:', response.data); + + if (response.data.errors) { + console.error('testMainDataTables: GraphQL Errors:', response.data.errors); + } + + const allData = response.data.data.mainDataTables || []; + console.log('testMainDataTables: All mainDataTables:', allData); + console.log('testMainDataTables: Count:', allData.length); + + // Check which records have VM data + const recordsWithVM = allData.filter(record => record.vm); + console.log('testMainDataTables: Records with VM:', recordsWithVM); + console.log('testMainDataTables: Records with VM count:', recordsWithVM.length); + + dispatch({ + type: "GET_MAIN_TABLES", + payload: { + mainDataTables: allData, + }, + }); + } catch (error) { + console.error("testMainDataTables: Error:", error); + } + }; +}; diff --git a/sge-frontend/src/redux/reducers/datas/index.js b/sge-frontend/src/redux/reducers/datas/index.js index 3e83483..ef80f05 100644 --- a/sge-frontend/src/redux/reducers/datas/index.js +++ b/sge-frontend/src/redux/reducers/datas/index.js @@ -30,7 +30,7 @@ const datasReducer = (state = initialState, action) => { case "GET_SUBSECTOR_BY_ID": return { ...state, - subSector: action.payload.subSector, + subSector: action.payload.subSector || {}, }; case "GET_ACTIVITY_SUBUNITS": return { diff --git a/sge-frontend/src/views/DataCenterManagement.js b/sge-frontend/src/views/DataCenterManagement.js index a30f298..1bb45f1 100644 --- a/sge-frontend/src/views/DataCenterManagement.js +++ b/sge-frontend/src/views/DataCenterManagement.js @@ -31,6 +31,8 @@ import withReactContent from "sweetalert2-react-content"; import { getDataCenters, createDataCenter, updateDataCenter, deleteDataCenter } from "../redux/actions/dataCenter"; import { useTranslation } from "react-i18next"; import { getAreas } from "../redux/actions/areas"; +import { getSectors, getSectorById, getSubSectorById, getConsuptionUnits } from "../redux/actions/datas"; +import { getAllEmissionSources } from "../redux/actions/emissionSources"; import { permissionCheck } from "../components/permission-check"; import { customFilterForSelect } from "../utility/Utils"; import { MapContainer, TileLayer, Marker, useMapEvents } from 'react-leaflet'; @@ -107,14 +109,33 @@ const DataCenterManagement = () => { address: "", latitude: null, longitude: null, - ayposURL: "" + ayposURL: "", + city: "", + emissionScopeId: null, + sectorId: null, + subSectorId: null, + emissionSourceId: null, + consuptionUnitId: null, + activitySubUnitId: null }); const [mapPosition, setMapPosition] = useState(null); const dataCenterStore = useSelector((state) => state.dataCenter); const areasStore = useSelector((state) => state.areas); + const datasStore = useSelector((state) => state.datas); + const emissionSourceStore = useSelector((state) => state.emissionSources); const [areasOptions, setAreasOptions] = useState([]); + const [sectorsOptions, setSectorsOptions] = useState([]); + const [subSectorsOptions, setSubSectorsOptions] = useState([]); + const [emissionSourcesOptions, setEmissionSourcesOptions] = useState([]); + const [consuptionUnitsOptions, setConsuptionUnitsOptions] = useState([]); + const [activitySubUnitsOptions, setActivitySubUnitsOptions] = useState([]); + const [emissionScopesOptions, setEmissionScopesOptions] = useState([]); + + // Add state for selected sector and sub sector like in data input + const [selectedSector, setSelectedSector] = useState(null); + const [selectedSubSector, setSelectedSubSector] = useState(null); const [editingDataCenter, setEditingDataCenter] = useState(null); @@ -205,6 +226,7 @@ const DataCenterManagement = () => { useEffect(() => { dispatch(getDataCenters()); dispatch(getAreas()); + dispatch(getSectors()); }, [dispatch]); useEffect(() => { @@ -216,6 +238,96 @@ const DataCenterManagement = () => { ); }, [areasStore]); + useEffect(() => { + setSectorsOptions( + datasStore?.sectors?.map((sector) => ({ + value: sector?.id, + label: sector?.tag, + })) + ); + }, [datasStore?.sectors]); + + useEffect(() => { + setSubSectorsOptions([]); + setSubSectorsOptions( + datasStore?.sector?.subSectors?.map((subSector) => ({ + value: subSector?.id, + label: subSector?.tag, + })) + ); + }, [datasStore?.sector]); + + useEffect(() => { + setActivitySubUnitsOptions( + datasStore?.subSector?.activitySubUnits?.map((activitySubUnit) => ({ + value: activitySubUnit?.id, + label: activitySubUnit?.tag, + })) + ); + }, [datasStore?.subSector]); + + useEffect(() => { + setEmissionSourcesOptions( + emissionSourceStore?.emissionSources + ?.filter((source) => source.convertUnitCheck != false) + ?.map((source) => ({ + value: source?.id, + label: source?.tag, + })) + ); + }, [emissionSourceStore?.emissionSources]); + + useEffect(() => { + if (selectedDataCenter?.emissionSourceId) { + dispatch( + getConsuptionUnits({ + id: selectedDataCenter?.emissionSourceId, + sector: selectedDataCenter?.sectorId, + }) + ); + } + }, [selectedDataCenter?.emissionSourceId]); + + useEffect(() => { + if (selectedSubSector != null) { + dispatch(getAllEmissionSources(selectedSubSector)); + } + }, [selectedSubSector]); + + useEffect(() => { + if (selectedSector != null) { + dispatch(getSectorById(selectedSector)); + } + }, [selectedSector]); + + useEffect(() => { + if (selectedSubSector != null) { + dispatch(getSubSectorById(selectedSubSector)); + } + }, [selectedSubSector]); + + useEffect(() => { + setConsuptionUnitsOptions( + datasStore?.consuptionUnits?.map((consuptionUnit) => ({ + value: consuptionUnit?.unit?.id, + label: consuptionUnit?.unit?.description, + })) + ); + }, [datasStore?.consuptionUnits]); + + useEffect(() => { + setEmissionScopesOptions([ + { + label: "Şehir İçi", + value: false, + }, + { + label: "Şehir Dışı", + value: true, + }, + ]); + }, []); + const handleEditDataCenter = (row) => { setEditingDataCenter(row); setSelectedDataCenter({ @@ -226,8 +338,20 @@ const DataCenterManagement = () => { address: row.address, latitude: row.latitude, longitude: row.longitude, - ayposURL: row.ayposURL + ayposURL: row.ayposURL, + city: row.city, + emissionScopeId: row.emissionScope?.id, + sectorId: row.sector?.id, + subSectorId: row.subSector?.id, + emissionSourceId: row.emissionSource?.id, + consuptionUnitId: row.consuptionUnit?.id, + activitySubUnitId: row.activitySubUnit?.id }); + + // Set the selected sector and sub sector for cascading dropdowns + setSelectedSector(row.sector?.id); + setSelectedSubSector(row.subSector?.id); + // Only set map position if we have both address and valid coordinates setMapPosition(row.address && row.latitude && row.longitude ? [row.latitude, row.longitude] : null); setShowAddModal(true); @@ -272,7 +396,14 @@ const DataCenterManagement = () => { // Ensure number is set for new data centers const dataToSubmit = { ...selectedDataCenter, - number: selectedDataCenter.number || 1 // Default to 1 if not set + number: selectedDataCenter.number || 1, // Default to 1 if not set + city: selectedDataCenter.city, // Add city to the payload + emissionScopeId: selectedDataCenter.emissionScopeId, + sectorId: selectedDataCenter.sectorId, + subSectorId: selectedDataCenter.subSectorId, + emissionSourceId: selectedDataCenter.emissionSourceId, + consuptionUnitId: selectedDataCenter.consuptionUnitId, + activitySubUnitId: selectedDataCenter.activitySubUnitId }; if (editingDataCenter) { @@ -284,12 +415,12 @@ const DataCenterManagement = () => { await dispatch(createDataCenter(dataToSubmit)); enqueueSnackbar(t("DataCenter.createSuccess"), { variant: "success" }); } - + handleCloseModal(); } catch (error) { - console.error("Operation error:", error); + console.error("Submit error:", error); enqueueSnackbar( - error?.message || (editingDataCenter ? t("DataCenter.updateError") : t("DataCenter.createError")), + error?.message || t("DataCenter.submitError"), { variant: "error" } ); } @@ -305,7 +436,8 @@ const DataCenterManagement = () => { address: "", latitude: null, longitude: null, - ayposURL: "" + ayposURL: "", + city: "" }); setMapPosition(null); setEditingDataCenter(null); @@ -352,7 +484,7 @@ const DataCenterManagement = () => { try { const response = await nominatimAxios.get(`/search?format=json&q=${encodeURIComponent(address)}`); - + if (response.data && response.data[0]) { const { lat, lon } = response.data[0]; const newPosition = [parseFloat(lat), parseFloat(lon)]; @@ -364,7 +496,7 @@ const DataCenterManagement = () => { })); return true; } - + // If no results found, clear the coordinates setMapPosition(null); setSelectedDataCenter(prev => ({ @@ -393,7 +525,7 @@ const DataCenterManagement = () => { ...prev, address: newAddress })); - + // If address is empty, clear the coordinates if (!newAddress.trim()) { setMapPosition(null); @@ -488,6 +620,24 @@ const DataCenterManagement = () => { /> + + + + + setSelectedDataCenter({ + ...selectedDataCenter, + city: e.target.value, + }) + } + /> + + @@ -536,6 +686,158 @@ const DataCenterManagement = () => { + + {/* Emission Scope Section */} + +
Emission Scope Configuration
+ + + + + option.value === selectedDataCenter.sectorId + )} + onChange={(option) => { + setSelectedSector(option?.value); + setSelectedDataCenter({ + ...selectedDataCenter, + sectorId: option?.value, + subSectorId: null, + emissionSourceId: null, + consuptionUnitId: null, + activitySubUnitId: null, + }); + }} + isClearable + filterOption={customFilterForSelect} + /> + + + + + + option.value === selectedDataCenter.emissionSourceId + )} + onChange={(option) => { + setSelectedDataCenter({ + ...selectedDataCenter, + emissionSourceId: option?.value, + consuptionUnitId: null, + }); + }} + isClearable + filterOption={customFilterForSelect} + isDisabled={!selectedDataCenter.subSectorId} + /> + + + + + + option.value === selectedDataCenter.activitySubUnitId + )} + onChange={(option) => { + setSelectedDataCenter({ + ...selectedDataCenter, + activitySubUnitId: option?.value, + }); + }} + isClearable + filterOption={customFilterForSelect} + isDisabled={!selectedDataCenter.subSectorId} + /> + + + diff --git a/sge-frontend/src/views/Graphics.js b/sge-frontend/src/views/Graphics.js index 86b1450..e293be3 100644 --- a/sge-frontend/src/views/Graphics.js +++ b/sge-frontend/src/views/Graphics.js @@ -1,1019 +1,1025 @@ - -import React, { useState, useEffect } from "react"; -import { - Button, - Card, - CardHeader, - CardTitle, - Col, - Dropdown, - DropdownToggle, - DropdownMenu, - DropdownItem, - Label, - Row, -} from "reactstrap"; -import Select from "react-select"; -import { useSelector, useDispatch } from "react-redux"; -import { useTranslation } from "react-i18next"; -import DataTable from "react-data-table-component"; -import { - getOrganisations, - getOrganisationById, -} from "../redux/actions/organisations"; -import { getAreasWithCriteria } from "../redux/actions/areas"; -import { getMainDataTables } from "../redux/actions/mainDataTables"; -import { editNumbers } from "../components/edit-numbers"; -import { PieChart } from "../components/graphics"; -import ConstantEnergyGraphics from "../components/subSector-graphics/ConstantEnergyGraphics"; -import TransportGraphics from "../components/subSector-graphics/TransportGraphics"; -import WasteGraphics from "../components/subSector-graphics/WasteGraphics"; -import { Download } from "react-feather"; -import html2canvas from "html2canvas"; -import jsPDF from "jspdf"; -import { default as SweetAlert } from "sweetalert2"; -import withReactContent from "sweetalert2-react-content"; -import { ChromePicker } from "react-color"; -import { customFilterForSelect } from "../utility/Utils"; -import PdfHeader from "../components/pdf-header"; - -const Swal = withReactContent(SweetAlert); - -const ColorPicker = ({ selectedColors, setSelectedColors }) => { - const [showColorPicker, setShowColorPicker] = useState(false); - const [currentColorIndex, setCurrentColorIndex] = useState(null); - - useEffect(() => { - const storedColors = localStorage.getItem("selectedColors"); - if (storedColors) { - setSelectedColors(JSON.parse(storedColors)); - } - }, []); - - useEffect(() => { - localStorage.setItem("selectedColors", JSON.stringify(selectedColors)); - }, [selectedColors]); - - const handleColorChange = (color) => { - const newColor = color.hex; - const updatedColors = [...selectedColors]; - updatedColors[currentColorIndex] = newColor; - setSelectedColors(updatedColors); - }; - - const handleColorClick = (index) => { - setCurrentColorIndex(index); - setShowColorPicker(true); - }; - - const handleCloseColorPicker = () => { - setCurrentColorIndex(null); - setShowColorPicker(false); - }; - - const handlePickerOutsideClick = (event) => { - // Renk seçici dışına tıklama kontrolü - if ( - event.target.closest(".color-picker-container") === null && - event.target.closest(".color-box") === null - ) { - handleCloseColorPicker(); - } - }; - - useEffect(() => { - // Tüm belgeye tıklama olayını dinle - document.addEventListener("click", handlePickerOutsideClick); - - return () => { - // Bileşen kaldırıldığında tıklama olayının dinlemesini kaldır - document.removeEventListener("click", handlePickerOutsideClick); - }; - }, []); - - return ( -
-
Grafik Renkleri
- {selectedColors.map((color, index) => ( -
handleColorClick(index)} - >
- ))} - {showColorPicker && ( -
- -
- )} -
- ); -}; - -const Graphics = () => { - const { t } = useTranslation(); - const dispatch = useDispatch(); - - const OrganisationsStore = useSelector((state) => state.organizations); - const areasStore = useSelector((state) => state.areas); - const mainDataTablesStore = useSelector((state) => state.mainDataTables); - - const [bringGraphics, setBringGraphics] = useState(false); - const [mainDataTables, setMainDataTables] = useState([]); - const [mainDataTablesFilterByYear, setMainDataTablesFilterByYear] = useState( - [] - ); - const [summaryData, setSummaryData] = useState([]); - const [pieChartData, setPieChartData] = useState([]); - const [constantEnergyData, setConstantEnergyData] = useState([]); - const [transportData, setTransportData] = useState([]); - const [transportSubSectorData, setTransportSubSectorData] = useState([]); - const [wasteData, setWasteData] = useState([]); - - const [organizationOptions, setOrganizationOptions] = useState([]); - const [areasOptions, setAreasOptions] = useState([]); - const [filter, setFilter] = useState(false); - const [filterOptions, setFilterOptions] = useState({ - sector: "", - area: "", - city: "", - district: "", - neighborhood: "", - year: "", - }); - - const [selectedOrganization, setSelectedOrganization] = useState(""); - const organizationId = localStorage.getItem("organizationId"); - const roleTag = localStorage.getItem("roleTag"); - - const currentYear = new Date().getFullYear(); - const renderYearOptions = () => { - const years = []; - for (let year = currentYear; year >= 1990; year--) { - years.push({ label: year, value: year }); - } - return years; - }; - - const [showConstantEnergy, setShowConstantEnergy] = useState(false); - const [showTransport, setShowTransport] = useState(false); - const [showWaste, setShowWaste] = useState(false); - - const [indexNumber, setIndexNumber] = useState(null); - - const [dropdownOpen, setDropdownOpen] = useState(false); - const [selectedOption, setSelectedOption] = useState(""); - - const [isPDFDownloading, setIsPDFDownloading] = useState(false); - const [hideTables, setHideTables] = useState(false); - const [hideComponents, setHideComponents] = useState({}); - - const initialColors = [ - "orange", - "gray", - "#028a4a", - "blue", - "pink", - "brown", - "purple", - ]; - const [selectedColors, setSelectedColors] = useState(initialColors); - - const serverSideColumnsOfMain = [ - { - name: t("EmissionSources.sector"), - selector: (row) => row.sector, - sortable: false, - cell: (row) => ( - - {row.sector?.tag || "-"} - - ), - }, - { - name: `Sera Gazı Miktarı (${t("DataInput.total")} tCO₂e)`, - selector: (row) => row.totalEmission, - sortable: false, - cell: (row) => ( - - {" "} - {editNumbers(row.totalEmission) || "-"} - - ), - }, - { - name: `${t("Oransal Dağılım")} %`, - selector: (row) => row.percentage, - sortable: false, - cell: (row) => ( - - {row.percentage || "-"} - - ), - }, - ]; - - useEffect(() => { - if (roleTag != "SUPER_ADMIN") setSelectedOrganization(organizationId); - }, []); - - useEffect(() => { - if (roleTag === "SUPER_ADMIN") { - dispatch(getOrganisations()); - } else { - dispatch(getOrganisationById(organizationId)); - } - }, []); - - useEffect(() => { - dispatch( - getAreasWithCriteria( - selectedOrganization?.value - ? selectedOrganization.value - : organizationId - ) - ); - }, [selectedOrganization]); - - useEffect(() => { - if (filterOptions?.year && filterOptions?.area) - dispatch( - getMainDataTables({ - filterOptions, - }) - ); - }, [filter]); - - useEffect(() => { - let organizationOptions = []; - - 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, - }) - ); - } - - setOrganizationOptions(organizationOptions); - }, [OrganisationsStore]); - - useEffect(() => { - setAreasOptions([]); - - const citiesOptions = - areasStore?.areasWithCriteria - ?.map((area) => - Array.isArray(area?.cities) // cities'in bir dizi olup olmadığını kontrol edin - ? area.cities.map((city) => ({ - value: city?.id, - label: city?.name, - type: "city", - })) - : [] - ) - .flat() || []; // Eğer map boş dönerse, `flat` sonrası boş bir dizi kullan - - - const districtsOptions = areasStore?.areasWithCriteria - ?.map((area) => { - return area?.districts?.map((district) => { - return { - value: district?.id, - label: district?.name + " (" + district?.city?.name + ")", - type: "district", - }; - }); - }) - .flat(); - - const neighborhoodsOptions = areasStore?.areasWithCriteria - ?.map((area) => { - return area?.neighborhoods?.map((neighborhood) => { - return { - value: neighborhood?.id, - label: - neighborhood?.name + - " (" + - neighborhood?.district?.name + - " / " + - neighborhood?.district?.city?.name + - ")", - type: "neighborhood", - }; - }); - }) - .flat(); - - setAreasOptions([ - ...citiesOptions || [], - ...districtsOptions || [], - ...neighborhoodsOptions || [], - ]); - }, [areasStore]); - - useEffect(() => { - if (mainDataTablesStore?.mainDataTables) { - setMainDataTablesFilterByYear(mainDataTablesStore?.mainDataTables); - } - }, [mainDataTablesStore.mainDataTables]); - - useEffect(() => { - if (mainDataTablesFilterByYear?.length > 0) { - let totalConstantEnergy = 0; - let totalTransport = 0; - let totalWaste = 0; - - for (let i = 0; i < mainDataTablesFilterByYear?.length; i++) { - if (mainDataTablesFilterByYear[i].sector?.tag === "Sabit Enerji") { - totalConstantEnergy += mainDataTablesFilterByYear[i].totalEmission; - } - if (mainDataTablesFilterByYear[i].sector?.tag === "Ulaşım") { - totalTransport += mainDataTablesFilterByYear[i].totalEmission; - } - if (mainDataTablesFilterByYear[i].sector?.tag === "Atık") { - totalWaste += mainDataTablesFilterByYear[i].totalEmission; - } - } - - let total = totalConstantEnergy + totalTransport + totalWaste; - - setMainDataTables([ - { - sector: { tag: "Sabit Enerji" }, - totalEmission: totalConstantEnergy, - percentage: ((totalConstantEnergy / total) * 100).toFixed(2) + "%", - }, - { - sector: { tag: "Ulaşım" }, - totalEmission: totalTransport, - percentage: ((totalTransport / total) * 100).toFixed(2) + "%", - }, - { - sector: { tag: "Atık" }, - totalEmission: totalWaste, - percentage: ((totalWaste / total) * 100).toFixed(2) + "%", - }, - { - sector: { tag: "Genel Toplam" }, - totalEmission: `${editNumbers(total)} tCO₂e`, - percentage: "100,00%", - }, - ]); - } - }, [mainDataTablesFilterByYear]); - - useEffect(() => { - let newChartData = mainDataTables.filter( - (data) => data.sector.tag != "Genel Toplam" - ); - setPieChartData(newChartData); - }, [mainDataTables]); - - useEffect(() => { - if (!mainDataTables) return; - - const sectorTags = ["Genel Toplam", "Sabit Enerji", "Ulaşım", "Atık"]; - - const filteredData = mainDataTables.filter((data) => - sectorTags.includes(data.sector.tag) - ); - - const summaryData = { - areaName: filterOptions.area.label, - totalEmission: filteredData.find( - (data) => data.sector.tag === "Genel Toplam" - )?.totalEmission, - constantEnergyTotalEmission: editNumbers( - filteredData.find((data) => data.sector.tag === "Sabit Enerji") - ?.totalEmission - ), - transportTotalEmission: editNumbers( - filteredData.find((data) => data.sector.tag === "Ulaşım")?.totalEmission - ), - wasteTotalEmission: editNumbers( - filteredData.find((data) => data.sector.tag === "Atık")?.totalEmission - ), - }; - - setSummaryData(summaryData); - }, [mainDataTables, filterOptions.area.label]); - - const calculateResult = (data, filterTag) => { - const filteredData = data.filter((item) => item.sector?.tag === filterTag); - - if (filterTag === "Ulaşım") { - setTransportSubSectorData(filteredData); - } - - const result = filteredData.reduce((result, item) => { - const existingItem = result.find( - (resultItem) => - resultItem.sector.id === item.sector.id && - resultItem.subSector.id === item.subSector.id - ); - if (existingItem) { - existingItem.totalEmission += item.totalEmission; - } else { - result.push({ - sector: item.sector, - subSector: item.subSector, - totalEmission: item.totalEmission, - }); - } - return result; - }, []); - - return calculateData(result); - }; - - const calculateData = (filteredData) => { - if (filteredData?.length > 0) { - const totalEmission = filteredData.reduce( - (sum, item) => sum + item.totalEmission, - 0 - ); - - const updatedData = filteredData.map((item) => { - const percentage = ((item.totalEmission / totalEmission) * 100).toFixed( - 2 - ); - return { ...item, percentage }; - }); - - updatedData.push({ - subSector: { tag: "Genel Toplam" }, - totalEmission: `${editNumbers(totalEmission)} tCO₂e`, - percentage: "100,00", - }); - - return updatedData; - } - }; - - useEffect(() => { - if (mainDataTablesFilterByYear?.length > 0) { - const newConstantEnergyData = calculateResult( - mainDataTablesFilterByYear, - "Sabit Enerji" - ); - setConstantEnergyData(newConstantEnergyData); - - const newTransportData = calculateResult( - mainDataTablesFilterByYear, - "Ulaşım" - ); - setTransportData(newTransportData); - - const newWasteData = calculateResult(mainDataTablesFilterByYear, "Atık"); - setWasteData(newWasteData); - } - }, [mainDataTablesFilterByYear]); - - const toggleDropdown = () => { - setDropdownOpen(!dropdownOpen); - }; - - const handleOptionSelect = (option) => { - setSelectedOption(option); - - const optionsMap = { - "TÜM SEKTÖRLER": { - showConstantEnergy: true, - showWaste: true, - showTransport: true, - }, - "Sabit Enerji": { - showConstantEnergy: true, - showWaste: false, - showTransport: false, - }, - Ulaşım: { - showConstantEnergy: false, - showWaste: false, - showTransport: true, - }, - Atık: { - showConstantEnergy: false, - showWaste: true, - showTransport: false, - }, - }; - - const { showConstantEnergy, showWaste, showTransport } = optionsMap[option]; - setShowConstantEnergy(showConstantEnergy); - setShowWaste(showWaste); - setShowTransport(showTransport); - }; - - const handleBringButtonPressed = () => { - setFilter(!filter); - //setBringGraphics(true); - }; - - const handleSelect = () => { - setBringGraphics(false); - setMainDataTables([]); - setMainDataTablesFilterByYear([]); - setPieChartData([]); - setIndexNumber(null); - setConstantEnergyData([]); - setShowConstantEnergy(false); - setTransportData([]); - setTransportSubSectorData([]); - setShowTransport(false); - setWasteData([]); - setShowWaste(false); - setSelectedOption(t("EmissionSources.sectors")); - }; - - const handleDownload = async () => { - setIsPDFDownloading(true); - - const result = await Swal.fire({ - title: `PDF çıktısı almak istediginize emin misiniz?`, - icon: "question", - showCancelButton: true, - confirmButtonText: "Evet", - cancelButtonText: t("Cruds.cancel"), - customClass: { - confirmButton: "btn btn-primary", - cancelButton: "btn btn-danger ml-1", - }, - buttonsStyling: false, - }); - if (result.value !== null && result.value === true) { - const input = [document.getElementById("graphics-container1")]; - if (constantEnergyData && showConstantEnergy) { - input.push( - document.getElementById("graphics-container2"), - document.getElementById("graphics-container3") - ); - } - if (transportData && showTransport) { - input.push( - document.getElementById("graphics-container4"), - document.getElementById("graphics-container5"), - document.getElementById("graphics-container6") - ); - } - if (wasteData && showWaste) { - input.push(document.getElementById("graphics-container-waste")); - } - - const generatePDF = async () => { - const doc = new jsPDF("p", "mm"); - - for (let i = 0; i < input.length; i++) { - const a = input[i]; - - const canvas = await html2canvas(a); - - const imgWidth = 208; - const pageHeight = 295; - const imgHeight = (canvas.height * imgWidth) / canvas.width; - let heightLeft = imgHeight; - let position = 0; - heightLeft -= pageHeight; - const img = canvas.toDataURL("image/png"); - doc.addImage( - img, - "PNG", - 0, - position, - imgWidth, - imgHeight, - "", - "FAST" - ); - while (heightLeft >= 0) { - position = heightLeft - imgHeight; - doc.addPage(); - doc.addImage( - canvas, - "PNG", - 0, - position, - imgWidth, - imgHeight, - "", - "FAST" - ); - heightLeft -= pageHeight; - } - if (input.length > i + 1) { - doc.addPage(); - } - } - - doc.save("rapor.pdf"); - setIsPDFDownloading(false); - }; - - generatePDF(); - } else { - setIsPDFDownloading(false); - } - }; - - const handleCheckboxChange = (componentName) => { - setHideComponents((prevState) => ({ - ...prevState, - [componentName]: !prevState[componentName], - })); - }; - - return ( -
- - - Grafikler - - - - - -
- - { - handleSelect(); - setFilterOptions({ - ...filterOptions, - city: "", - district: "", - neighborhood: "", - area: value, - [value.type]: value.value, - }); - }} - /> -
- - -
- - { - setHideTables(e.target.checked); - }} - /> - -
- )} -
- - - {mainDataTables?.length > 1 && ( - - - - )} - {mainDataTables?.length === 0 && bringGraphics && ( - - )} -
- {mainDataTables?.length > 1 && isPDFDownloading && ( - <> - - - - {summaryData.areaName} idari sınırları içerisindeki toplam sera - gazı emisyonu {summaryData.totalEmission} olarak ortaya - çıkmıştır. Hesaplanan emisyon değerinin sektör bazlı dağılımına - bakıldığında; Sabit Enerji sektöründe{" "} - {summaryData.constantEnergyTotalEmission} tCO₂e, Ulaşım - sektöründe {summaryData.transportTotalEmission} tCO₂e - ve Atık sektöründe - {summaryData.wasteTotalEmission} tCO₂e - {" "} - sera gazı emisyonu gerçekleştiği görülmektedir. - - - - )} - {mainDataTables?.length > 1 && ( - <> - - {!hideTables && - !(isPDFDownloading && hideComponents["sectors-dataTable"]) && ( - - {!isPDFDownloading && ( - - handleCheckboxChange("sectors-dataTable") - } - /> - )} - - {filterOptions.area.label} Sera Gazı Emisyon Dağılımı - - } - className="react-dataTable mt-1 border-black" - columns={serverSideColumnsOfMain} - data={mainDataTables} - noDataComponent={ -

- {t("DataInput.report")} - {t("Warnings.notFound")} -

- } - customStyles={ - isPDFDownloading - ? { - rows: { - fontSize: "25px", - }, - headCells: { - style: { - fontSize: "23px", - }, - }, - } - : "" - } - /> - - )} -
- - {!(isPDFDownloading && hideComponents["sectors-pie-chart"]) && ( -
- {!isPDFDownloading && ( - handleCheckboxChange("sectors-pie-chart")} - /> - )} - -
- )} - {indexNumber != null && ( -
- {!isPDFDownloading && ( - setIndexNumber(null)} - /> - )} - - -
- )} -
- - )} -
- {mainDataTables?.length > 1 && !isPDFDownloading && ( - - - - - {selectedOption - ? selectedOption.toUpperCase() - : t("EmissionSources.sectors")} - - - handleOptionSelect("TÜM SEKTÖRLER")} - > - TÜM SEKTÖRLER - - {pieChartData - .filter((data) => data.totalEmission != 0) - .map((data, index) => ( - handleOptionSelect(data.sector.tag)} - > - {data.sector.tag.toUpperCase()} - - ))} - - - - - )} - {showConstantEnergy && constantEnergyData && ( - - )} - {showTransport && transportData && ( - - )} - {showWaste && wasteData && ( - - )} - - ); -}; - -export default Graphics; + +import React, { useState, useEffect } from "react"; +import { + Button, + Card, + CardHeader, + CardTitle, + Col, + Dropdown, + DropdownToggle, + DropdownMenu, + DropdownItem, + Label, + Row, +} from "reactstrap"; +import Select from "react-select"; +import { useSelector, useDispatch } from "react-redux"; +import { useTranslation } from "react-i18next"; +import DataTable from "react-data-table-component"; +import { + getDataCenters, + getDataCenterVMs, +} from "../redux/actions/dataCenter"; +import { getAreasByDataCenter } from "../redux/actions/areas"; +import { getMainDataTablesByVMs, testMainDataTables } from "../redux/actions/mainDataTables"; +import { editNumbers } from "../components/edit-numbers"; +import { PieChart } from "../components/graphics"; +import ConstantEnergyGraphics from "../components/subSector-graphics/ConstantEnergyGraphics"; +import TransportGraphics from "../components/subSector-graphics/TransportGraphics"; +import WasteGraphics from "../components/subSector-graphics/WasteGraphics"; +import { Download } from "react-feather"; +import html2canvas from "html2canvas"; +import jsPDF from "jspdf"; +import { default as SweetAlert } from "sweetalert2"; +import withReactContent from "sweetalert2-react-content"; +import { ChromePicker } from "react-color"; +import { customFilterForSelect } from "../utility/Utils"; +import PdfHeader from "../components/pdf-header"; + +const Swal = withReactContent(SweetAlert); + +const ColorPicker = ({ selectedColors, setSelectedColors }) => { + const [showColorPicker, setShowColorPicker] = useState(false); + const [currentColorIndex, setCurrentColorIndex] = useState(null); + + useEffect(() => { + const storedColors = localStorage.getItem("selectedColors"); + if (storedColors) { + setSelectedColors(JSON.parse(storedColors)); + } + }, []); + + useEffect(() => { + localStorage.setItem("selectedColors", JSON.stringify(selectedColors)); + }, [selectedColors]); + + const handleColorChange = (color) => { + const newColor = color.hex; + const updatedColors = [...selectedColors]; + updatedColors[currentColorIndex] = newColor; + setSelectedColors(updatedColors); + }; + + const handleColorClick = (index) => { + setCurrentColorIndex(index); + setShowColorPicker(true); + }; + + const handleCloseColorPicker = () => { + setCurrentColorIndex(null); + setShowColorPicker(false); + }; + + const handlePickerOutsideClick = (event) => { + // Renk seçici dışına tıklama kontrolü + if ( + event.target.closest(".color-picker-container") === null && + event.target.closest(".color-box") === null + ) { + handleCloseColorPicker(); + } + }; + + useEffect(() => { + // Tüm belgeye tıklama olayını dinle + document.addEventListener("click", handlePickerOutsideClick); + + return () => { + // Bileşen kaldırıldığında tıklama olayının dinlemesini kaldır + document.removeEventListener("click", handlePickerOutsideClick); + }; + }, []); + + return ( +
+
Grafik Renkleri
+ {selectedColors.map((color, index) => ( +
handleColorClick(index)} + >
+ ))} + {showColorPicker && ( +
+ +
+ )} +
+ ); +}; + +const Graphics = () => { + const { t } = useTranslation(); + const dispatch = useDispatch(); + + const dataCenterStore = useSelector((state) => state.dataCenter); + const areasStore = useSelector((state) => state.areas); + const mainDataTablesStore = useSelector((state) => state.mainDataTables); + + const [bringGraphics, setBringGraphics] = useState(false); + const [mainDataTables, setMainDataTables] = useState([]); + const [mainDataTablesFilterByYear, setMainDataTablesFilterByYear] = useState( + [] + ); + const [summaryData, setSummaryData] = useState([]); + const [pieChartData, setPieChartData] = useState([]); + const [constantEnergyData, setConstantEnergyData] = useState([]); + const [transportData, setTransportData] = useState([]); + const [transportSubSectorData, setTransportSubSectorData] = useState([]); + const [wasteData, setWasteData] = useState([]); + + const [dataCenterOptions, setDataCenterOptions] = useState([]); + const [areasOptions, setAreasOptions] = useState([]); + const [filter, setFilter] = useState(false); + const [filterOptions, setFilterOptions] = useState({ + sector: "", + area: "", + city: "", + district: "", + neighborhood: "", + year: "", + }); + + const [selectedDataCenter, setSelectedDataCenter] = useState(""); + const [dataCenterVMs, setDataCenterVMs] = useState([]); + const roleTag = localStorage.getItem("roleTag"); + + const currentYear = new Date().getFullYear(); + const renderYearOptions = () => { + const years = []; + for (let year = currentYear; year >= 1990; year--) { + years.push({ label: year, value: year }); + } + return years; + }; + + const [showConstantEnergy, setShowConstantEnergy] = useState(false); + const [showTransport, setShowTransport] = useState(false); + const [showWaste, setShowWaste] = useState(false); + + const [indexNumber, setIndexNumber] = useState(null); + + const [dropdownOpen, setDropdownOpen] = useState(false); + const [selectedOption, setSelectedOption] = useState(""); + + const [isPDFDownloading, setIsPDFDownloading] = useState(false); + const [hideTables, setHideTables] = useState(false); + const [hideComponents, setHideComponents] = useState({}); + + const initialColors = [ + "orange", + "gray", + "#028a4a", + "blue", + "pink", + "brown", + "purple", + ]; + const [selectedColors, setSelectedColors] = useState(initialColors); + + const serverSideColumnsOfMain = [ + { + name: t("EmissionSources.sector"), + selector: (row) => row.sector, + sortable: false, + cell: (row) => ( + + {row.sector?.tag || "-"} + + ), + }, + { + name: `Sera Gazı Miktarı (${t("DataInput.total")} tCO₂e)`, + selector: (row) => row.totalEmission, + sortable: false, + cell: (row) => ( + + {" "} + {editNumbers(row.totalEmission) || "-"} + + ), + }, + { + name: `${t("Oransal Dağılım")} %`, + selector: (row) => row.percentage, + sortable: false, + cell: (row) => ( + + {row.percentage || "-"} + + ), + }, + ]; + + useEffect(() => { + dispatch(getDataCenters()); + }, []); + + useEffect(() => { + console.log('Data center selection changed:', selectedDataCenter); + if (selectedDataCenter?.value) { + console.log('Fetching data for data center:', selectedDataCenter.value); + // Get areas for the selected data center + dispatch( + getAreasByDataCenter(selectedDataCenter.value) + ); + + // Get VMs for the selected data center + getDataCenterVMs(selectedDataCenter.value).then(vms => { + console.log('VMs received for data center:', vms); + setDataCenterVMs(vms); + }); + } else { + console.log('No data center selected'); + setDataCenterVMs([]); + } + }, [selectedDataCenter]); + + useEffect(() => { + console.log('Debug useEffect:', { + filterOptionsYear: filterOptions?.year, + selectedDataCenter: selectedDataCenter, + dataCenterVMsLength: dataCenterVMs.length, + filter: filter + }); + + if (filterOptions?.year && selectedDataCenter && dataCenterVMs.length > 0) { + const vmIds = dataCenterVMs.map(vm => vm.id); + console.log('Fetching main data tables with VM IDs:', vmIds); + console.log('Filter options:', filterOptions); + dispatch( + getMainDataTablesByVMs({ + vmIds, + filterOptions, + }) + ); + } else { + console.log('Conditions not met for fetching data:', { + hasYear: !!filterOptions?.year, + hasSelectedDataCenter: !!selectedDataCenter, + vmCount: dataCenterVMs.length + }); + } + }, [filter, dataCenterVMs, dispatch, filterOptions, selectedDataCenter]); + + useEffect(() => { + let dataCenterOptions = []; + + if (dataCenterStore?.dataCenters && dataCenterStore.dataCenters.length > 0) { + dataCenterOptions = dataCenterStore.dataCenters.map((dataCenter) => ({ + value: dataCenter.id, + label: dataCenter.dataCenter, + externalId: dataCenter.externalId, + })); + } + + setDataCenterOptions(dataCenterOptions); + }, [dataCenterStore]); + + useEffect(() => { + setAreasOptions([]); + + const citiesOptions = + areasStore?.areasWithCriteria + ?.map((area) => + Array.isArray(area?.cities) // cities'in bir dizi olup olmadığını kontrol edin + ? area.cities.map((city) => ({ + value: city?.id, + label: city?.name, + type: "city", + })) + : [] + ) + .flat() || []; // Eğer map boş dönerse, `flat` sonrası boş bir dizi kullan + + + const districtsOptions = areasStore?.areasWithCriteria + ?.map((area) => { + return area?.districts?.map((district) => { + return { + value: district?.id, + label: district?.name + " (" + district?.city?.name + ")", + type: "district", + }; + }); + }) + .flat(); + + const neighborhoodsOptions = areasStore?.areasWithCriteria + ?.map((area) => { + return area?.neighborhoods?.map((neighborhood) => { + return { + value: neighborhood?.id, + label: + neighborhood?.name + + " (" + + neighborhood?.district?.name + + " / " + + neighborhood?.district?.city?.name + + ")", + type: "neighborhood", + }; + }); + }) + .flat(); + + setAreasOptions([ + ...citiesOptions || [], + ...districtsOptions || [], + ...neighborhoodsOptions || [], + ]); + }, [areasStore]); + + useEffect(() => { + console.log('mainDataTablesStore changed:', mainDataTablesStore?.mainDataTables); + console.log('mainDataTablesStore full state:', mainDataTablesStore); + if (mainDataTablesStore?.mainDataTables) { + console.log('Setting mainDataTablesFilterByYear from store:', mainDataTablesStore.mainDataTables); + setMainDataTablesFilterByYear(mainDataTablesStore?.mainDataTables); + } else { + console.log('No mainDataTables in store'); + } + }, [mainDataTablesStore.mainDataTables]); + + useEffect(() => { + console.log('mainDataTablesFilterByYear changed:', mainDataTablesFilterByYear); + console.log('mainDataTablesFilterByYear length:', mainDataTablesFilterByYear?.length); + console.log('mainDataTablesFilterByYear data:', mainDataTablesFilterByYear); + + if (mainDataTablesFilterByYear?.length > 0) { + let totalConstantEnergy = 0; + let totalTransport = 0; + let totalWaste = 0; + + for (let i = 0; i < mainDataTablesFilterByYear?.length; i++) { + console.log('Processing record:', mainDataTablesFilterByYear[i]); + if (mainDataTablesFilterByYear[i].sector?.tag === "Sabit Enerji") { + totalConstantEnergy += mainDataTablesFilterByYear[i].totalEmission; + } + if (mainDataTablesFilterByYear[i].sector?.tag === "Ulaşım") { + totalTransport += mainDataTablesFilterByYear[i].totalEmission; + } + if (mainDataTablesFilterByYear[i].sector?.tag === "Atık") { + totalWaste += mainDataTablesFilterByYear[i].totalEmission; + } + } + + console.log('Calculated totals:', { totalConstantEnergy, totalTransport, totalWaste }); + + let total = totalConstantEnergy + totalTransport + totalWaste; + + const processedData = [ + { + sector: { tag: "Sabit Enerji" }, + totalEmission: totalConstantEnergy, + percentage: ((totalConstantEnergy / total) * 100).toFixed(2) + "%", + }, + { + sector: { tag: "Ulaşım" }, + totalEmission: totalTransport, + percentage: ((totalTransport / total) * 100).toFixed(2) + "%", + }, + { + sector: { tag: "Atık" }, + totalEmission: totalWaste, + percentage: ((totalWaste / total) * 100).toFixed(2) + "%", + }, + { + sector: { tag: "Genel Toplam" }, + totalEmission: `${editNumbers(total)} tCO₂e`, + percentage: "100,00%", + }, + ]; + + console.log('Setting mainDataTables:', processedData); + setMainDataTables(processedData); + } else { + console.log('No mainDataTablesFilterByYear data found. Length:', mainDataTablesFilterByYear?.length); + console.log('mainDataTablesStore state:', mainDataTablesStore); + } + }, [mainDataTablesFilterByYear]); + + useEffect(() => { + console.log('mainDataTables changed for pie chart:', mainDataTables); + let newChartData = mainDataTables.filter( + (data) => data.sector.tag != "Genel Toplam" + ); + console.log('Setting pieChartData:', newChartData); + setPieChartData(newChartData); + }, [mainDataTables]); + + useEffect(() => { + if (!mainDataTables) return; + + const sectorTags = ["Genel Toplam", "Sabit Enerji", "Ulaşım", "Atık"]; + + const filteredData = mainDataTables.filter((data) => + sectorTags.includes(data.sector.tag) + ); + + const summaryData = { + areaName: selectedDataCenter?.label || "Seçili Veri Merkezi", + totalEmission: filteredData.find( + (data) => data.sector.tag === "Genel Toplam" + )?.totalEmission, + constantEnergyTotalEmission: editNumbers( + filteredData.find((data) => data.sector.tag === "Sabit Enerji") + ?.totalEmission + ), + transportTotalEmission: editNumbers( + filteredData.find((data) => data.sector.tag === "Ulaşım")?.totalEmission + ), + wasteTotalEmission: editNumbers( + filteredData.find((data) => data.sector.tag === "Atık")?.totalEmission + ), + }; + + setSummaryData(summaryData); + }, [mainDataTables, selectedDataCenter]); + + const calculateResult = (data, filterTag) => { + const filteredData = data.filter((item) => item.sector?.tag === filterTag); + + if (filterTag === "Ulaşım") { + setTransportSubSectorData(filteredData); + } + + const result = filteredData.reduce((result, item) => { + const existingItem = result.find( + (resultItem) => + resultItem.sector.id === item.sector.id && + resultItem.subSector.id === item.subSector.id + ); + if (existingItem) { + existingItem.totalEmission += item.totalEmission; + } else { + result.push({ + sector: item.sector, + subSector: item.subSector, + totalEmission: item.totalEmission, + }); + } + return result; + }, []); + + return calculateData(result); + }; + + const calculateData = (filteredData) => { + if (filteredData?.length > 0) { + const totalEmission = filteredData.reduce( + (sum, item) => sum + item.totalEmission, + 0 + ); + + const updatedData = filteredData.map((item) => { + const percentage = ((item.totalEmission / totalEmission) * 100).toFixed( + 2 + ); + return { ...item, percentage }; + }); + + updatedData.push({ + subSector: { tag: "Genel Toplam" }, + totalEmission: `${editNumbers(totalEmission)} tCO₂e`, + percentage: "100,00", + }); + + return updatedData; + } + }; + + useEffect(() => { + if (mainDataTablesFilterByYear?.length > 0) { + const newConstantEnergyData = calculateResult( + mainDataTablesFilterByYear, + "Sabit Enerji" + ); + setConstantEnergyData(newConstantEnergyData); + + const newTransportData = calculateResult( + mainDataTablesFilterByYear, + "Ulaşım" + ); + setTransportData(newTransportData); + + const newWasteData = calculateResult(mainDataTablesFilterByYear, "Atık"); + setWasteData(newWasteData); + } + }, [mainDataTablesFilterByYear]); + + const toggleDropdown = () => { + setDropdownOpen(!dropdownOpen); + }; + + const handleOptionSelect = (option) => { + setSelectedOption(option); + + const optionsMap = { + "TÜM SEKTÖRLER": { + showConstantEnergy: true, + showWaste: true, + showTransport: true, + }, + "Sabit Enerji": { + showConstantEnergy: true, + showWaste: false, + showTransport: false, + }, + Ulaşım: { + showConstantEnergy: false, + showWaste: false, + showTransport: true, + }, + Atık: { + showConstantEnergy: false, + showWaste: true, + showTransport: false, + }, + }; + + const { showConstantEnergy, showWaste, showTransport } = optionsMap[option]; + setShowConstantEnergy(showConstantEnergy); + setShowWaste(showWaste); + setShowTransport(showTransport); + }; + + const handleBringButtonPressed = () => { + console.log('Getir button pressed'); + console.log('Current state:', { + selectedDataCenter, + filterOptions, + dataCenterVMs, + filter + }); + setFilter(!filter); + setBringGraphics(true); + }; + + const handleSelect = () => { + setBringGraphics(false); + setMainDataTables([]); + setMainDataTablesFilterByYear([]); + setPieChartData([]); + setIndexNumber(null); + setConstantEnergyData([]); + setShowConstantEnergy(false); + setTransportData([]); + setTransportSubSectorData([]); + setShowTransport(false); + setWasteData([]); + setShowWaste(false); + setSelectedOption(t("EmissionSources.sectors")); + }; + + const handleDownload = async () => { + setIsPDFDownloading(true); + + const result = await Swal.fire({ + title: `PDF çıktısı almak istediginize emin misiniz?`, + icon: "question", + showCancelButton: true, + confirmButtonText: "Evet", + cancelButtonText: t("Cruds.cancel"), + customClass: { + confirmButton: "btn btn-primary", + cancelButton: "btn btn-danger ml-1", + }, + buttonsStyling: false, + }); + if (result.value !== null && result.value === true) { + const input = [document.getElementById("graphics-container1")]; + if (constantEnergyData && showConstantEnergy) { + input.push( + document.getElementById("graphics-container2"), + document.getElementById("graphics-container3") + ); + } + if (transportData && showTransport) { + input.push( + document.getElementById("graphics-container4"), + document.getElementById("graphics-container5"), + document.getElementById("graphics-container6") + ); + } + if (wasteData && showWaste) { + input.push(document.getElementById("graphics-container-waste")); + } + + const generatePDF = async () => { + const doc = new jsPDF("p", "mm"); + + for (let i = 0; i < input.length; i++) { + const a = input[i]; + + const canvas = await html2canvas(a); + + const imgWidth = 208; + const pageHeight = 295; + const imgHeight = (canvas.height * imgWidth) / canvas.width; + let heightLeft = imgHeight; + let position = 0; + heightLeft -= pageHeight; + const img = canvas.toDataURL("image/png"); + doc.addImage( + img, + "PNG", + 0, + position, + imgWidth, + imgHeight, + "", + "FAST" + ); + while (heightLeft >= 0) { + position = heightLeft - imgHeight; + doc.addPage(); + doc.addImage( + canvas, + "PNG", + 0, + position, + imgWidth, + imgHeight, + "", + "FAST" + ); + heightLeft -= pageHeight; + } + if (input.length > i + 1) { + doc.addPage(); + } + } + + doc.save("rapor.pdf"); + setIsPDFDownloading(false); + }; + + generatePDF(); + } else { + setIsPDFDownloading(false); + } + }; + + const handleCheckboxChange = (componentName) => { + setHideComponents((prevState) => ({ + ...prevState, + [componentName]: !prevState[componentName], + })); + }; + + return ( +
+ + + Grafikler + + + + + +
+ + { + handleSelect(); + setFilterOptions({ + ...filterOptions, + year: value, + }); + }} + /> +
+ + +
+
+ + +
+ {mainDataTables?.length > 1 && ( +
+ { + setHideTables(e.target.checked); + }} + /> + +
+ )} +
+ +
+ {mainDataTables?.length > 1 && ( + + + + )} + {mainDataTables?.length === 0 && bringGraphics && ( + + )} +
+ {mainDataTables?.length > 1 && isPDFDownloading && ( + <> + + + + {summaryData.areaName} idari sınırları içerisindeki toplam sera + gazı emisyonu {summaryData.totalEmission} olarak ortaya + çıkmıştır. Hesaplanan emisyon değerinin sektör bazlı dağılımına + bakıldığında; Sabit Enerji sektöründe{" "} + {summaryData.constantEnergyTotalEmission} tCO₂e, Ulaşım + sektöründe {summaryData.transportTotalEmission} tCO₂e + ve Atık sektöründe + {summaryData.wasteTotalEmission} tCO₂e + {" "} + sera gazı emisyonu gerçekleştiği görülmektedir. + + + + )} + {mainDataTables?.length > 1 && ( + <> + + {!hideTables && + !(isPDFDownloading && hideComponents["sectors-dataTable"]) && ( + + {!isPDFDownloading && ( + + handleCheckboxChange("sectors-dataTable") + } + /> + )} + + {selectedDataCenter?.label || "Seçili Veri Merkezi"} Sera Gazı Emisyon Dağılımı + + } + className="react-dataTable mt-1 border-black" + columns={serverSideColumnsOfMain} + data={mainDataTables} + noDataComponent={ +

+ {t("DataInput.report")} + {t("Warnings.notFound")} +

+ } + customStyles={ + isPDFDownloading + ? { + rows: { + fontSize: "25px", + }, + headCells: { + style: { + fontSize: "23px", + }, + }, + } + : "" + } + /> + + )} +
+ + {!(isPDFDownloading && hideComponents["sectors-pie-chart"]) && ( +
+ {!isPDFDownloading && ( + handleCheckboxChange("sectors-pie-chart")} + /> + )} + +
+ )} + {indexNumber != null && ( +
+ {!isPDFDownloading && ( + setIndexNumber(null)} + /> + )} + + +
+ )} +
+ + )} +
+ {mainDataTables?.length > 1 && !isPDFDownloading && ( + + + + + {selectedOption + ? selectedOption.toUpperCase() + : t("EmissionSources.sectors")} + + + handleOptionSelect("TÜM SEKTÖRLER")} + > + TÜM SEKTÖRLER + + {pieChartData + .filter((data) => data.totalEmission != 0) + .map((data, index) => ( + handleOptionSelect(data.sector.tag)} + > + {data.sector.tag.toUpperCase()} + + ))} + + + + + )} + {showConstantEnergy && constantEnergyData && ( + + )} + {showTransport && transportData && ( + + )} + {showWaste && wasteData && ( + + )} +
+ ); +}; + +export default Graphics;