forked from BLC/sgeUpdated
Add datacenter with multiple emission source and inputs
This commit is contained in:
@@ -251,8 +251,8 @@ export const createDataCenter = (dataCenterData) => {
|
|||||||
emissionScopeId: dataCenterData.emissionScopeId || null,
|
emissionScopeId: dataCenterData.emissionScopeId || null,
|
||||||
sectorId: dataCenterData.sectorId || null,
|
sectorId: dataCenterData.sectorId || null,
|
||||||
subSectorId: dataCenterData.subSectorId || null,
|
subSectorId: dataCenterData.subSectorId || null,
|
||||||
emissionSourceId: dataCenterData.emissionSourceId || null,
|
dataCenterEmissionSources:
|
||||||
consuptionUnitId: dataCenterData.consuptionUnitId || null,
|
dataCenterData.dataCenterEmissionSources || [],
|
||||||
activitySubUnitId: dataCenterData.activitySubUnitId || null,
|
activitySubUnitId: dataCenterData.activitySubUnitId || null,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -382,8 +382,8 @@ export const updateDataCenter = (id, dataCenterData) => {
|
|||||||
emissionScopeId: dataCenterData.emissionScopeId || null,
|
emissionScopeId: dataCenterData.emissionScopeId || null,
|
||||||
sectorId: dataCenterData.sectorId || null,
|
sectorId: dataCenterData.sectorId || null,
|
||||||
subSectorId: dataCenterData.subSectorId || null,
|
subSectorId: dataCenterData.subSectorId || null,
|
||||||
emissionSourceId: dataCenterData.emissionSourceId || null,
|
dataCenterEmissionSources:
|
||||||
consuptionUnitId: dataCenterData.consuptionUnitId || null,
|
dataCenterData.dataCenterEmissionSources || [],
|
||||||
activitySubUnitId: dataCenterData.activitySubUnitId || null,
|
activitySubUnitId: dataCenterData.activitySubUnitId || null,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -28,26 +28,37 @@ import { Edit } from "@mui/icons-material";
|
|||||||
import { useSnackbar } from "notistack";
|
import { useSnackbar } from "notistack";
|
||||||
import { default as SweetAlert } from "sweetalert2";
|
import { default as SweetAlert } from "sweetalert2";
|
||||||
import withReactContent from "sweetalert2-react-content";
|
import withReactContent from "sweetalert2-react-content";
|
||||||
import { getDataCenters, createDataCenter, updateDataCenter, deleteDataCenter, getEmissionScopes } from "../redux/actions/dataCenter";
|
import {
|
||||||
|
getDataCenters,
|
||||||
|
createDataCenter,
|
||||||
|
updateDataCenter,
|
||||||
|
deleteDataCenter,
|
||||||
|
getEmissionScopes,
|
||||||
|
} from "../redux/actions/dataCenter";
|
||||||
import { getAreas, getAreasWithCriteria } from "../redux/actions/areas";
|
import { getAreas, getAreasWithCriteria } from "../redux/actions/areas";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { getSectors, getSectorById, getSubSectorById, getConsuptionUnits } from "../redux/actions/datas";
|
import {
|
||||||
|
getSectors,
|
||||||
|
getSectorById,
|
||||||
|
getSubSectorById,
|
||||||
|
getConsuptionUnits,
|
||||||
|
} from "../redux/actions/datas";
|
||||||
import { getAllEmissionSources } from "../redux/actions/emissionSources";
|
import { getAllEmissionSources } from "../redux/actions/emissionSources";
|
||||||
import { permissionCheck } from "../components/permission-check";
|
import { permissionCheck } from "../components/permission-check";
|
||||||
import { customFilterForSelect } from "../utility/Utils";
|
import { customFilterForSelect } from "../utility/Utils";
|
||||||
import { MapContainer, TileLayer, Marker, useMapEvents } from 'react-leaflet';
|
import { MapContainer, TileLayer, Marker, useMapEvents } from "react-leaflet";
|
||||||
import 'leaflet/dist/leaflet.css';
|
import "leaflet/dist/leaflet.css";
|
||||||
import L from 'leaflet';
|
import L from "leaflet";
|
||||||
import axios from 'axios';
|
import axios from "axios";
|
||||||
import { debounce } from 'lodash';
|
import { debounce } from "lodash";
|
||||||
|
|
||||||
// Add Nominatim service configuration
|
// Add Nominatim service configuration
|
||||||
const NOMINATIM_BASE_URL = 'https://nominatim.openstreetmap.org';
|
const NOMINATIM_BASE_URL = "https://nominatim.openstreetmap.org";
|
||||||
const nominatimAxios = axios.create({
|
const nominatimAxios = axios.create({
|
||||||
baseURL: NOMINATIM_BASE_URL,
|
baseURL: NOMINATIM_BASE_URL,
|
||||||
headers: {
|
headers: {
|
||||||
'User-Agent': 'SGE-DataCenter-Management' // Required by Nominatim's usage policy
|
"User-Agent": "SGE-DataCenter-Management", // Required by Nominatim's usage policy
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const Swal = withReactContent(SweetAlert);
|
const Swal = withReactContent(SweetAlert);
|
||||||
@@ -55,9 +66,9 @@ const Swal = withReactContent(SweetAlert);
|
|||||||
// Fix Leaflet marker icon issue
|
// Fix Leaflet marker icon issue
|
||||||
delete L.Icon.Default.prototype._getIconUrl;
|
delete L.Icon.Default.prototype._getIconUrl;
|
||||||
L.Icon.Default.mergeOptions({
|
L.Icon.Default.mergeOptions({
|
||||||
iconRetinaUrl: require('leaflet/dist/images/marker-icon-2x.png'),
|
iconRetinaUrl: require("leaflet/dist/images/marker-icon-2x.png"),
|
||||||
iconUrl: require('leaflet/dist/images/marker-icon.png'),
|
iconUrl: require("leaflet/dist/images/marker-icon.png"),
|
||||||
shadowUrl: require('leaflet/dist/images/marker-shadow.png')
|
shadowUrl: require("leaflet/dist/images/marker-shadow.png"),
|
||||||
});
|
});
|
||||||
|
|
||||||
// Map marker component that handles clicks
|
// Map marker component that handles clicks
|
||||||
@@ -66,30 +77,33 @@ const MapMarker = ({ position, setPosition, setSelectedDataCenter }) => {
|
|||||||
click(e) {
|
click(e) {
|
||||||
setPosition([e.latlng.lat, e.latlng.lng]);
|
setPosition([e.latlng.lat, e.latlng.lng]);
|
||||||
// Use Nominatim reverse geocoding directly
|
// Use Nominatim reverse geocoding directly
|
||||||
nominatimAxios.get(`/reverse?format=json&lat=${e.latlng.lat}&lon=${e.latlng.lng}`)
|
nominatimAxios
|
||||||
.then(response => {
|
.get(`/reverse?format=json&lat=${e.latlng.lat}&lon=${e.latlng.lng}`)
|
||||||
|
.then((response) => {
|
||||||
const address = response.data.display_name;
|
const address = response.data.display_name;
|
||||||
setSelectedDataCenter(prev => ({
|
setSelectedDataCenter((prev) => ({
|
||||||
...prev,
|
...prev,
|
||||||
address,
|
address,
|
||||||
latitude: e.latlng.lat,
|
latitude: e.latlng.lat,
|
||||||
longitude: e.latlng.lng
|
longitude: e.latlng.lng,
|
||||||
}));
|
}));
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch((error) => {
|
||||||
console.error('Error getting address:', error);
|
console.error("Error getting address:", error);
|
||||||
// Still update coordinates even if address lookup fails
|
// Still update coordinates even if address lookup fails
|
||||||
setSelectedDataCenter(prev => ({
|
setSelectedDataCenter((prev) => ({
|
||||||
...prev,
|
...prev,
|
||||||
latitude: e.latlng.lat,
|
latitude: e.latlng.lat,
|
||||||
longitude: e.latlng.lng
|
longitude: e.latlng.lng,
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// Only render marker if position exists and has valid coordinates
|
// Only render marker if position exists and has valid coordinates
|
||||||
return position && position[0] && position[1] ? <Marker position={position} /> : null;
|
return position && position[0] && position[1] ? (
|
||||||
|
<Marker position={position} />
|
||||||
|
) : null;
|
||||||
};
|
};
|
||||||
|
|
||||||
const DataCenterManagement = () => {
|
const DataCenterManagement = () => {
|
||||||
@@ -115,15 +129,14 @@ const DataCenterManagement = () => {
|
|||||||
emissionScopeId: null,
|
emissionScopeId: null,
|
||||||
sectorId: null,
|
sectorId: null,
|
||||||
subSectorId: null,
|
subSectorId: null,
|
||||||
emissionSourceId: null,
|
dataCenterEmissionSources: [], // Array of emission sources with consumption units
|
||||||
consuptionUnitId: null,
|
activitySubUnitId: null,
|
||||||
activitySubUnitId: null
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const [mapPosition, setMapPosition] = useState(null);
|
const [mapPosition, setMapPosition] = useState(null);
|
||||||
|
|
||||||
const dataCenterStore = useSelector((state) => {
|
const dataCenterStore = useSelector((state) => {
|
||||||
console.log('DataCenter Store:', state.dataCenter);
|
console.log("DataCenter Store:", state.dataCenter);
|
||||||
return state.dataCenter;
|
return state.dataCenter;
|
||||||
});
|
});
|
||||||
const emissionScopeStore = useSelector((state) => state.emissionScope);
|
const emissionScopeStore = useSelector((state) => state.emissionScope);
|
||||||
@@ -138,7 +151,7 @@ const DataCenterManagement = () => {
|
|||||||
const [emissionScopesOptions, setEmissionScopesOptions] = useState([]);
|
const [emissionScopesOptions, setEmissionScopesOptions] = useState([]);
|
||||||
const [areasOptions, setAreasOptions] = useState([]);
|
const [areasOptions, setAreasOptions] = useState([]);
|
||||||
const [citiesOptions, setCitiesOptions] = useState([]);
|
const [citiesOptions, setCitiesOptions] = useState([]);
|
||||||
|
|
||||||
// Add state for selected sector and sub sector like in data input
|
// Add state for selected sector and sub sector like in data input
|
||||||
const [selectedSector, setSelectedSector] = useState(null);
|
const [selectedSector, setSelectedSector] = useState(null);
|
||||||
const [selectedSubSector, setSelectedSubSector] = useState(null);
|
const [selectedSubSector, setSelectedSubSector] = useState(null);
|
||||||
@@ -170,7 +183,7 @@ const DataCenterManagement = () => {
|
|||||||
<Button
|
<Button
|
||||||
color="primary"
|
color="primary"
|
||||||
size="sm"
|
size="sm"
|
||||||
onClick={() => window.open(row.ayposURL, '_blank')}
|
onClick={() => window.open(row.ayposURL, "_blank")}
|
||||||
>
|
>
|
||||||
Dashboard
|
Dashboard
|
||||||
</Button>
|
</Button>
|
||||||
@@ -200,7 +213,9 @@ const DataCenterManagement = () => {
|
|||||||
onClick={() => handleEditDataCenter(row)}
|
onClick={() => handleEditDataCenter(row)}
|
||||||
>
|
>
|
||||||
<Edit size={15} />
|
<Edit size={15} />
|
||||||
<span className="align-middle ml-50">{t("Cruds.edit")}</span>
|
<span className="align-middle ml-50">
|
||||||
|
{t("Cruds.edit")}
|
||||||
|
</span>
|
||||||
</DropdownItem>
|
</DropdownItem>
|
||||||
)}
|
)}
|
||||||
{permissionCheck("data_center_delete") && (
|
{permissionCheck("data_center_delete") && (
|
||||||
@@ -210,7 +225,9 @@ const DataCenterManagement = () => {
|
|||||||
onClick={() => handleDeleteDataCenter(row)}
|
onClick={() => handleDeleteDataCenter(row)}
|
||||||
>
|
>
|
||||||
<Trash size={15} />
|
<Trash size={15} />
|
||||||
<span className="align-middle ml-50">{t("Cruds.delete")}</span>
|
<span className="align-middle ml-50">
|
||||||
|
{t("Cruds.delete")}
|
||||||
|
</span>
|
||||||
</DropdownItem>
|
</DropdownItem>
|
||||||
)}
|
)}
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
@@ -269,16 +286,41 @@ const DataCenterManagement = () => {
|
|||||||
);
|
);
|
||||||
}, [emissionSourceStore?.emissionSources]);
|
}, [emissionSourceStore?.emissionSources]);
|
||||||
|
|
||||||
|
// Remove the old emission source effect since we now handle it in the emission sources component
|
||||||
|
// useEffect(() => {
|
||||||
|
// if (selectedDataCenter?.emissionSourceId) {
|
||||||
|
// dispatch(
|
||||||
|
// getConsuptionUnits({
|
||||||
|
// id: selectedDataCenter?.emissionSourceId,
|
||||||
|
// sector: selectedDataCenter?.sectorId,
|
||||||
|
// })
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// }, [selectedDataCenter?.emissionSourceId]);
|
||||||
|
|
||||||
|
// Ensure there's always at least one emission source entry for new data centers
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (selectedDataCenter?.emissionSourceId) {
|
if (
|
||||||
dispatch(
|
showAddModal &&
|
||||||
getConsuptionUnits({
|
!editingDataCenter &&
|
||||||
id: selectedDataCenter?.emissionSourceId,
|
selectedDataCenter.dataCenterEmissionSources.length === 0
|
||||||
sector: selectedDataCenter?.sectorId,
|
) {
|
||||||
})
|
setSelectedDataCenter((prev) => ({
|
||||||
);
|
...prev,
|
||||||
|
dataCenterEmissionSources: [
|
||||||
|
{
|
||||||
|
emissionSourceId: null,
|
||||||
|
consuptionUnitId: null,
|
||||||
|
isDefault: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
}, [selectedDataCenter?.emissionSourceId]);
|
}, [
|
||||||
|
showAddModal,
|
||||||
|
editingDataCenter,
|
||||||
|
selectedDataCenter.dataCenterEmissionSources.length,
|
||||||
|
]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (selectedSubSector != null) {
|
if (selectedSubSector != null) {
|
||||||
@@ -352,8 +394,18 @@ const DataCenterManagement = () => {
|
|||||||
}, [selectedDataCenter.areaId, areasStore?.areas]);
|
}, [selectedDataCenter.areaId, areasStore?.areas]);
|
||||||
|
|
||||||
const handleEditDataCenter = (row) => {
|
const handleEditDataCenter = (row) => {
|
||||||
console.log('Editing data center:', row);
|
console.log("Editing data center:", row);
|
||||||
setEditingDataCenter(row);
|
setEditingDataCenter(row);
|
||||||
|
|
||||||
|
// Convert dataCenterEmissionSources to the format expected by the form
|
||||||
|
const emissionSources = row.dataCenterEmissionSources
|
||||||
|
? row.dataCenterEmissionSources.map((dces) => ({
|
||||||
|
emissionSourceId: dces.emissionSource?.id,
|
||||||
|
consuptionUnitId: dces.consuptionUnit?.id,
|
||||||
|
isDefault: dces.isDefault || false,
|
||||||
|
}))
|
||||||
|
: [];
|
||||||
|
|
||||||
setSelectedDataCenter({
|
setSelectedDataCenter({
|
||||||
name: row.dataCenter,
|
name: row.dataCenter,
|
||||||
externalId: row.externalId?.toString(),
|
externalId: row.externalId?.toString(),
|
||||||
@@ -368,17 +420,20 @@ const DataCenterManagement = () => {
|
|||||||
emissionScopeId: row.emissionScope?.id || null,
|
emissionScopeId: row.emissionScope?.id || null,
|
||||||
sectorId: row.sector?.id || null,
|
sectorId: row.sector?.id || null,
|
||||||
subSectorId: row.subSector?.id || null,
|
subSectorId: row.subSector?.id || null,
|
||||||
emissionSourceId: row.emissionSource?.id || null,
|
dataCenterEmissionSources: emissionSources,
|
||||||
consuptionUnitId: row.consuptionUnit?.id || null,
|
activitySubUnitId: row.activitySubUnit?.id || null,
|
||||||
activitySubUnitId: row.activitySubUnit?.id || null
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Set the selected sector and sub sector for cascading dropdowns
|
// Set the selected sector and sub sector for cascading dropdowns
|
||||||
setSelectedSector(row.sector?.id);
|
setSelectedSector(row.sector?.id);
|
||||||
setSelectedSubSector(row.subSector?.id);
|
setSelectedSubSector(row.subSector?.id);
|
||||||
|
|
||||||
// Only set map position if we have both address and valid coordinates
|
// Only set map position if we have both address and valid coordinates
|
||||||
setMapPosition(row.address && row.latitude && row.longitude ? [row.latitude, row.longitude] : null);
|
setMapPosition(
|
||||||
|
row.address && row.latitude && row.longitude
|
||||||
|
? [row.latitude, row.longitude]
|
||||||
|
: null
|
||||||
|
);
|
||||||
setShowAddModal(true);
|
setShowAddModal(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -403,17 +458,16 @@ const DataCenterManagement = () => {
|
|||||||
enqueueSnackbar(t("DataCenter.deleteSuccess"), { variant: "success" });
|
enqueueSnackbar(t("DataCenter.deleteSuccess"), { variant: "success" });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Delete error:", error);
|
console.error("Delete error:", error);
|
||||||
enqueueSnackbar(
|
enqueueSnackbar(error?.message || t("DataCenter.deleteError"), {
|
||||||
error?.message || t("DataCenter.deleteError"),
|
variant: "error",
|
||||||
{ variant: "error" }
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const validateForm = () => {
|
const validateForm = () => {
|
||||||
const errors = [];
|
const errors = [];
|
||||||
|
|
||||||
// Required fields validation
|
// Required fields validation
|
||||||
if (!selectedDataCenter.name?.trim()) {
|
if (!selectedDataCenter.name?.trim()) {
|
||||||
errors.push(t("DataCenter.nameRequired"));
|
errors.push(t("DataCenter.nameRequired"));
|
||||||
@@ -448,7 +502,7 @@ const DataCenterManagement = () => {
|
|||||||
try {
|
try {
|
||||||
const lat = parseFloat(selectedDataCenter.latitude);
|
const lat = parseFloat(selectedDataCenter.latitude);
|
||||||
const lng = parseFloat(selectedDataCenter.longitude);
|
const lng = parseFloat(selectedDataCenter.longitude);
|
||||||
|
|
||||||
if (isNaN(lat) || lat < -90 || lat > 90) {
|
if (isNaN(lat) || lat < -90 || lat > 90) {
|
||||||
errors.push(t("DataCenter.invalidLatitude"));
|
errors.push(t("DataCenter.invalidLatitude"));
|
||||||
}
|
}
|
||||||
@@ -473,23 +527,60 @@ const DataCenterManagement = () => {
|
|||||||
if (selectedDataCenter.subSectorId && !selectedDataCenter.sectorId) {
|
if (selectedDataCenter.subSectorId && !selectedDataCenter.sectorId) {
|
||||||
errors.push(t("DataCenter.sectorRequired"));
|
errors.push(t("DataCenter.sectorRequired"));
|
||||||
}
|
}
|
||||||
if (selectedDataCenter.emissionSourceId && !selectedDataCenter.subSectorId) {
|
if (
|
||||||
errors.push(t("DataCenter.subSectorRequired"));
|
selectedDataCenter.activitySubUnitId &&
|
||||||
}
|
!selectedDataCenter.subSectorId
|
||||||
if (selectedDataCenter.consuptionUnitId && !selectedDataCenter.emissionSourceId) {
|
) {
|
||||||
errors.push(t("DataCenter.emissionSourceRequired"));
|
|
||||||
}
|
|
||||||
if (selectedDataCenter.activitySubUnitId && !selectedDataCenter.subSectorId) {
|
|
||||||
errors.push(t("DataCenter.subSectorRequiredForActivity"));
|
errors.push(t("DataCenter.subSectorRequiredForActivity"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Emission sources validations
|
||||||
|
if (selectedDataCenter.dataCenterEmissionSources.length > 0) {
|
||||||
|
const validSources = selectedDataCenter.dataCenterEmissionSources.filter(
|
||||||
|
(source) => source.emissionSourceId && source.consuptionUnitId
|
||||||
|
);
|
||||||
|
|
||||||
|
if (validSources.length === 0) {
|
||||||
|
errors.push(t("DataCenter.atLeastOneEmissionSource"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for incomplete emission sources
|
||||||
|
selectedDataCenter.dataCenterEmissionSources.forEach((source, index) => {
|
||||||
|
if (
|
||||||
|
(source.emissionSourceId && !source.consuptionUnitId) ||
|
||||||
|
(!source.emissionSourceId && source.consuptionUnitId)
|
||||||
|
) {
|
||||||
|
errors.push(
|
||||||
|
t("DataCenter.incompleteEmissionSource", { index: index + 1 })
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Check for duplicate emission sources
|
||||||
|
const sourceIds = validSources.map((s) => s.emissionSourceId);
|
||||||
|
const duplicates = sourceIds.filter(
|
||||||
|
(id, index) => sourceIds.indexOf(id) !== index
|
||||||
|
);
|
||||||
|
if (duplicates.length > 0) {
|
||||||
|
errors.push(t("DataCenter.duplicateEmissionSources"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure exactly one default emission source
|
||||||
|
const defaultSources = validSources.filter((s) => s.isDefault);
|
||||||
|
if (defaultSources.length === 0) {
|
||||||
|
errors.push(t("DataCenter.oneDefaultEmissionSourceRequired"));
|
||||||
|
} else if (defaultSources.length > 1) {
|
||||||
|
errors.push(t("DataCenter.onlyOneDefaultEmissionSourceAllowed"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return errors;
|
return errors;
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async () => {
|
||||||
const validationErrors = validateForm();
|
const validationErrors = validateForm();
|
||||||
if (validationErrors.length > 0) {
|
if (validationErrors.length > 0) {
|
||||||
validationErrors.forEach(error => {
|
validationErrors.forEach((error) => {
|
||||||
enqueueSnackbar(error, { variant: "error" });
|
enqueueSnackbar(error, { variant: "error" });
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
@@ -498,20 +589,26 @@ const DataCenterManagement = () => {
|
|||||||
try {
|
try {
|
||||||
// Format data according to GraphQL input type
|
// Format data according to GraphQL input type
|
||||||
const dataToSubmit = {
|
const dataToSubmit = {
|
||||||
dataCenter: selectedDataCenter.name,
|
name: selectedDataCenter.name,
|
||||||
externalId: parseInt(selectedDataCenter.externalId),
|
externalId: parseInt(selectedDataCenter.externalId),
|
||||||
number: parseInt(selectedDataCenter.number || "1"),
|
number: parseInt(selectedDataCenter.number || "1"),
|
||||||
address: selectedDataCenter.address,
|
address: selectedDataCenter.address,
|
||||||
areaId: selectedDataCenter.areaId,
|
areaId: selectedDataCenter.areaId,
|
||||||
latitude: selectedDataCenter.latitude ? parseFloat(selectedDataCenter.latitude) : null,
|
latitude: selectedDataCenter.latitude
|
||||||
longitude: selectedDataCenter.longitude ? parseFloat(selectedDataCenter.longitude) : null,
|
? parseFloat(selectedDataCenter.latitude)
|
||||||
|
: null,
|
||||||
|
longitude: selectedDataCenter.longitude
|
||||||
|
? parseFloat(selectedDataCenter.longitude)
|
||||||
|
: null,
|
||||||
ayposURL: selectedDataCenter.ayposURL,
|
ayposURL: selectedDataCenter.ayposURL,
|
||||||
emissionScopeId: selectedDataCenter.emissionScopeId,
|
emissionScopeId: selectedDataCenter.emissionScopeId,
|
||||||
sectorId: selectedDataCenter.sectorId,
|
sectorId: selectedDataCenter.sectorId,
|
||||||
subSectorId: selectedDataCenter.subSectorId,
|
subSectorId: selectedDataCenter.subSectorId,
|
||||||
emissionSourceId: selectedDataCenter.emissionSourceId,
|
dataCenterEmissionSources:
|
||||||
consuptionUnitId: selectedDataCenter.consuptionUnitId,
|
selectedDataCenter.dataCenterEmissionSources.filter(
|
||||||
activitySubUnitId: selectedDataCenter.activitySubUnitId
|
(source) => source.emissionSourceId && source.consuptionUnitId
|
||||||
|
),
|
||||||
|
activitySubUnitId: selectedDataCenter.activitySubUnitId,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (editingDataCenter) {
|
if (editingDataCenter) {
|
||||||
@@ -523,26 +620,27 @@ const DataCenterManagement = () => {
|
|||||||
await dispatch(createDataCenter(dataToSubmit));
|
await dispatch(createDataCenter(dataToSubmit));
|
||||||
enqueueSnackbar(t("DataCenter.createSuccess"), { variant: "success" });
|
enqueueSnackbar(t("DataCenter.createSuccess"), { variant: "success" });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refresh the data centers list
|
// Refresh the data centers list
|
||||||
await dispatch(getDataCenters());
|
await dispatch(getDataCenters());
|
||||||
|
|
||||||
handleCloseModal();
|
handleCloseModal();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Submit error:", error);
|
console.error("Submit error:", error);
|
||||||
|
|
||||||
// Handle specific error cases
|
// Handle specific error cases
|
||||||
if (error.message?.includes("duplicate")) {
|
if (error.message?.includes("duplicate")) {
|
||||||
enqueueSnackbar(t("DataCenter.duplicateExternalId"), { variant: "error" });
|
enqueueSnackbar(t("DataCenter.duplicateExternalId"), {
|
||||||
|
variant: "error",
|
||||||
|
});
|
||||||
} else if (error.message?.includes("permission")) {
|
} else if (error.message?.includes("permission")) {
|
||||||
enqueueSnackbar(t("Common.noPermission"), { variant: "error" });
|
enqueueSnackbar(t("Common.noPermission"), { variant: "error" });
|
||||||
} else if (error.message?.includes("not found")) {
|
} else if (error.message?.includes("not found")) {
|
||||||
enqueueSnackbar(t("DataCenter.resourceNotFound"), { variant: "error" });
|
enqueueSnackbar(t("DataCenter.resourceNotFound"), { variant: "error" });
|
||||||
} else {
|
} else {
|
||||||
enqueueSnackbar(
|
enqueueSnackbar(error?.message || t("DataCenter.submitError"), {
|
||||||
error?.message || t("DataCenter.submitError"),
|
variant: "error",
|
||||||
{ variant: "error" }
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -554,13 +652,28 @@ const DataCenterManagement = () => {
|
|||||||
externalId: "",
|
externalId: "",
|
||||||
number: "",
|
number: "",
|
||||||
address: "",
|
address: "",
|
||||||
|
areaId: null,
|
||||||
|
cityId: null,
|
||||||
latitude: null,
|
latitude: null,
|
||||||
longitude: null,
|
longitude: null,
|
||||||
ayposURL: "",
|
ayposURL: "",
|
||||||
city: ""
|
city: "",
|
||||||
|
emissionScopeId: null,
|
||||||
|
sectorId: null,
|
||||||
|
subSectorId: null,
|
||||||
|
dataCenterEmissionSources: [
|
||||||
|
{
|
||||||
|
emissionSourceId: null,
|
||||||
|
consuptionUnitId: null,
|
||||||
|
isDefault: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
activitySubUnitId: null,
|
||||||
});
|
});
|
||||||
setMapPosition(null);
|
setMapPosition(null);
|
||||||
setEditingDataCenter(null);
|
setEditingDataCenter(null);
|
||||||
|
setSelectedSector(null);
|
||||||
|
setSelectedSubSector(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleFilter = (e) => {
|
const handleFilter = (e) => {
|
||||||
@@ -594,45 +707,47 @@ const DataCenterManagement = () => {
|
|||||||
const geocodeAddress = useCallback(async (address) => {
|
const geocodeAddress = useCallback(async (address) => {
|
||||||
if (!address || !address.trim()) {
|
if (!address || !address.trim()) {
|
||||||
setMapPosition(null);
|
setMapPosition(null);
|
||||||
setSelectedDataCenter(prev => ({
|
setSelectedDataCenter((prev) => ({
|
||||||
...prev,
|
...prev,
|
||||||
latitude: null,
|
latitude: null,
|
||||||
longitude: null
|
longitude: null,
|
||||||
}));
|
}));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await nominatimAxios.get(`/search?format=json&q=${encodeURIComponent(address)}`);
|
const response = await nominatimAxios.get(
|
||||||
|
`/search?format=json&q=${encodeURIComponent(address)}`
|
||||||
|
);
|
||||||
|
|
||||||
if (response.data && response.data[0]) {
|
if (response.data && response.data[0]) {
|
||||||
const { lat, lon } = response.data[0];
|
const { lat, lon } = response.data[0];
|
||||||
const newPosition = [parseFloat(lat), parseFloat(lon)];
|
const newPosition = [parseFloat(lat), parseFloat(lon)];
|
||||||
setMapPosition(newPosition);
|
setMapPosition(newPosition);
|
||||||
setSelectedDataCenter(prev => ({
|
setSelectedDataCenter((prev) => ({
|
||||||
...prev,
|
...prev,
|
||||||
latitude: parseFloat(lat),
|
latitude: parseFloat(lat),
|
||||||
longitude: parseFloat(lon)
|
longitude: parseFloat(lon),
|
||||||
}));
|
}));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no results found, clear the coordinates
|
// If no results found, clear the coordinates
|
||||||
setMapPosition(null);
|
setMapPosition(null);
|
||||||
setSelectedDataCenter(prev => ({
|
setSelectedDataCenter((prev) => ({
|
||||||
...prev,
|
...prev,
|
||||||
latitude: null,
|
latitude: null,
|
||||||
longitude: null
|
longitude: null,
|
||||||
}));
|
}));
|
||||||
return false;
|
return false;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error geocoding address:', error);
|
console.error("Error geocoding address:", error);
|
||||||
// On error, clear the coordinates
|
// On error, clear the coordinates
|
||||||
setMapPosition(null);
|
setMapPosition(null);
|
||||||
setSelectedDataCenter(prev => ({
|
setSelectedDataCenter((prev) => ({
|
||||||
...prev,
|
...prev,
|
||||||
latitude: null,
|
latitude: null,
|
||||||
longitude: null
|
longitude: null,
|
||||||
}));
|
}));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -641,18 +756,18 @@ const DataCenterManagement = () => {
|
|||||||
// Update the address input handler
|
// Update the address input handler
|
||||||
const handleAddressChange = (e) => {
|
const handleAddressChange = (e) => {
|
||||||
const newAddress = e.target.value;
|
const newAddress = e.target.value;
|
||||||
setSelectedDataCenter(prev => ({
|
setSelectedDataCenter((prev) => ({
|
||||||
...prev,
|
...prev,
|
||||||
address: newAddress
|
address: newAddress,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// If address is empty, clear the coordinates
|
// If address is empty, clear the coordinates
|
||||||
if (!newAddress.trim()) {
|
if (!newAddress.trim()) {
|
||||||
setMapPosition(null);
|
setMapPosition(null);
|
||||||
setSelectedDataCenter(prev => ({
|
setSelectedDataCenter((prev) => ({
|
||||||
...prev,
|
...prev,
|
||||||
latitude: null,
|
latitude: null,
|
||||||
longitude: null
|
longitude: null,
|
||||||
}));
|
}));
|
||||||
} else {
|
} else {
|
||||||
// If address is not empty, try to geocode it after a delay
|
// If address is not empty, try to geocode it after a delay
|
||||||
@@ -675,9 +790,7 @@ const DataCenterManagement = () => {
|
|||||||
size="lg"
|
size="lg"
|
||||||
>
|
>
|
||||||
<ModalHeader toggle={handleCloseModal}>
|
<ModalHeader toggle={handleCloseModal}>
|
||||||
{editingDataCenter
|
{editingDataCenter ? t("DataCenter.edit") : t("DataCenter.add")}
|
||||||
? t("DataCenter.edit")
|
|
||||||
: t("DataCenter.add")}
|
|
||||||
</ModalHeader>
|
</ModalHeader>
|
||||||
<ModalBody>
|
<ModalBody>
|
||||||
<Form>
|
<Form>
|
||||||
@@ -685,7 +798,8 @@ const DataCenterManagement = () => {
|
|||||||
<Col sm="12">
|
<Col sm="12">
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<Label for="name">
|
<Label for="name">
|
||||||
{t("DataCenter.name")} <span className="text-danger">*</span>
|
{t("DataCenter.name")}{" "}
|
||||||
|
<span className="text-danger">*</span>
|
||||||
</Label>
|
</Label>
|
||||||
<Input
|
<Input
|
||||||
type="text"
|
type="text"
|
||||||
@@ -705,7 +819,8 @@ const DataCenterManagement = () => {
|
|||||||
<Col sm="6">
|
<Col sm="6">
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<Label for="externalId">
|
<Label for="externalId">
|
||||||
{t("DataCenter.externalId")} <span className="text-danger">*</span>
|
{t("DataCenter.externalId")}{" "}
|
||||||
|
<span className="text-danger">*</span>
|
||||||
</Label>
|
</Label>
|
||||||
<Input
|
<Input
|
||||||
type="text"
|
type="text"
|
||||||
@@ -814,10 +929,12 @@ const DataCenterManagement = () => {
|
|||||||
</div>
|
</div>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
</Col>
|
</Col>
|
||||||
|
|
||||||
{/* Emission Scope Section */}
|
{/* Emission Scope Section */}
|
||||||
<Col sm="12">
|
<Col sm="12">
|
||||||
<h5 className="mt-3 mb-2 text-primary">Emission Scope Configuration</h5>
|
<h5 className="mt-3 mb-2 text-primary">
|
||||||
|
Emission Scope Configuration
|
||||||
|
</h5>
|
||||||
</Col>
|
</Col>
|
||||||
<Col sm="6">
|
<Col sm="6">
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
@@ -828,7 +945,8 @@ const DataCenterManagement = () => {
|
|||||||
placeholder="Select emission scope"
|
placeholder="Select emission scope"
|
||||||
options={emissionScopesOptions}
|
options={emissionScopesOptions}
|
||||||
value={emissionScopesOptions?.find(
|
value={emissionScopesOptions?.find(
|
||||||
(option) => option.value === selectedDataCenter.emissionScopeId
|
(option) =>
|
||||||
|
option.value === selectedDataCenter.emissionScopeId
|
||||||
)}
|
)}
|
||||||
onChange={(option) =>
|
onChange={(option) =>
|
||||||
setSelectedDataCenter({
|
setSelectedDataCenter({
|
||||||
@@ -843,7 +961,9 @@ const DataCenterManagement = () => {
|
|||||||
</Col>
|
</Col>
|
||||||
<Col sm="6">
|
<Col sm="6">
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<Label for="sector">Sector <span className="text-danger">*</span></Label>
|
<Label for="sector">
|
||||||
|
Sector <span className="text-danger">*</span>
|
||||||
|
</Label>
|
||||||
<Select
|
<Select
|
||||||
id="sector"
|
id="sector"
|
||||||
name="sector"
|
name="sector"
|
||||||
@@ -858,8 +978,13 @@ const DataCenterManagement = () => {
|
|||||||
...selectedDataCenter,
|
...selectedDataCenter,
|
||||||
sectorId: option?.value,
|
sectorId: option?.value,
|
||||||
subSectorId: null,
|
subSectorId: null,
|
||||||
emissionSourceId: null,
|
dataCenterEmissionSources: [
|
||||||
consuptionUnitId: null,
|
{
|
||||||
|
emissionSourceId: null,
|
||||||
|
consuptionUnitId: null,
|
||||||
|
isDefault: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
activitySubUnitId: null,
|
activitySubUnitId: null,
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
@@ -877,15 +1002,21 @@ const DataCenterManagement = () => {
|
|||||||
placeholder="Select sub sector"
|
placeholder="Select sub sector"
|
||||||
options={subSectorsOptions}
|
options={subSectorsOptions}
|
||||||
value={subSectorsOptions?.find(
|
value={subSectorsOptions?.find(
|
||||||
(option) => option.value === selectedDataCenter.subSectorId
|
(option) =>
|
||||||
|
option.value === selectedDataCenter.subSectorId
|
||||||
)}
|
)}
|
||||||
onChange={(option) => {
|
onChange={(option) => {
|
||||||
setSelectedSubSector(option?.value);
|
setSelectedSubSector(option?.value);
|
||||||
setSelectedDataCenter({
|
setSelectedDataCenter({
|
||||||
...selectedDataCenter,
|
...selectedDataCenter,
|
||||||
subSectorId: option?.value,
|
subSectorId: option?.value,
|
||||||
emissionSourceId: null,
|
dataCenterEmissionSources: [
|
||||||
consuptionUnitId: null,
|
{
|
||||||
|
emissionSourceId: null,
|
||||||
|
consuptionUnitId: null,
|
||||||
|
isDefault: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
activitySubUnitId: null,
|
activitySubUnitId: null,
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
@@ -895,51 +1026,191 @@ const DataCenterManagement = () => {
|
|||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
</Col>
|
</Col>
|
||||||
<Col sm="6">
|
<Col sm="12">
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<Label for="emissionSource">Emission Source</Label>
|
<Label>Emission Sources & Consumption Units</Label>
|
||||||
<Select
|
<div className="border p-3 rounded bg-light">
|
||||||
id="emissionSource"
|
<small className="text-muted mb-2 d-block">
|
||||||
name="emissionSource"
|
Configure emission sources for this data center. At least
|
||||||
placeholder="Select emission source"
|
one emission source with consumption unit is required.
|
||||||
options={emissionSourcesOptions}
|
</small>
|
||||||
value={emissionSourcesOptions?.find(
|
{selectedDataCenter.dataCenterEmissionSources.map(
|
||||||
(option) => option.value === selectedDataCenter.emissionSourceId
|
(source, index) => (
|
||||||
|
<Row key={index} className="mb-2 align-items-end">
|
||||||
|
<Col sm="5">
|
||||||
|
<Label
|
||||||
|
for={`emissionSource-${index}`}
|
||||||
|
className="form-label"
|
||||||
|
>
|
||||||
|
Emission Source *
|
||||||
|
</Label>
|
||||||
|
<Select
|
||||||
|
id={`emissionSource-${index}`}
|
||||||
|
placeholder="Select emission source..."
|
||||||
|
options={emissionSourcesOptions}
|
||||||
|
value={emissionSourcesOptions?.find(
|
||||||
|
(option) =>
|
||||||
|
option.value === source.emissionSourceId
|
||||||
|
)}
|
||||||
|
onChange={(option) => {
|
||||||
|
const updatedSources = [
|
||||||
|
...selectedDataCenter.dataCenterEmissionSources,
|
||||||
|
];
|
||||||
|
updatedSources[index] = {
|
||||||
|
...updatedSources[index],
|
||||||
|
emissionSourceId: option?.value,
|
||||||
|
consuptionUnitId: null, // Reset consumption unit when emission source changes
|
||||||
|
};
|
||||||
|
setSelectedDataCenter({
|
||||||
|
...selectedDataCenter,
|
||||||
|
dataCenterEmissionSources: updatedSources,
|
||||||
|
});
|
||||||
|
// Fetch consumption units for the selected emission source
|
||||||
|
if (option?.value) {
|
||||||
|
dispatch(
|
||||||
|
getConsuptionUnits({
|
||||||
|
id: option.value,
|
||||||
|
sector: selectedDataCenter?.sectorId,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
isClearable
|
||||||
|
filterOption={customFilterForSelect}
|
||||||
|
isDisabled={!selectedDataCenter.subSectorId}
|
||||||
|
styles={{
|
||||||
|
placeholder: (provided) => ({
|
||||||
|
...provided,
|
||||||
|
color: "#6e6b7b",
|
||||||
|
}),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
<Col sm="4">
|
||||||
|
<Label
|
||||||
|
for={`consuptionUnit-${index}`}
|
||||||
|
className="form-label"
|
||||||
|
>
|
||||||
|
Consumption Unit *
|
||||||
|
</Label>
|
||||||
|
<Select
|
||||||
|
id={`consuptionUnit-${index}`}
|
||||||
|
placeholder="Select consumption unit..."
|
||||||
|
options={consuptionUnitsOptions}
|
||||||
|
value={consuptionUnitsOptions?.find(
|
||||||
|
(option) =>
|
||||||
|
option.value === source.consuptionUnitId
|
||||||
|
)}
|
||||||
|
onChange={(option) => {
|
||||||
|
const updatedSources = [
|
||||||
|
...selectedDataCenter.dataCenterEmissionSources,
|
||||||
|
];
|
||||||
|
updatedSources[index] = {
|
||||||
|
...updatedSources[index],
|
||||||
|
consuptionUnitId: option?.value,
|
||||||
|
};
|
||||||
|
setSelectedDataCenter({
|
||||||
|
...selectedDataCenter,
|
||||||
|
dataCenterEmissionSources: updatedSources,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
isClearable
|
||||||
|
filterOption={customFilterForSelect}
|
||||||
|
isDisabled={!source.emissionSourceId}
|
||||||
|
styles={{
|
||||||
|
placeholder: (provided) => ({
|
||||||
|
...provided,
|
||||||
|
color: "#6e6b7b",
|
||||||
|
}),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
<Col sm="3">
|
||||||
|
<Label className="form-label d-block">
|
||||||
|
Actions
|
||||||
|
</Label>
|
||||||
|
<div className="d-flex gap-2">
|
||||||
|
<Button
|
||||||
|
color={
|
||||||
|
source.isDefault
|
||||||
|
? "primary"
|
||||||
|
: "outline-secondary"
|
||||||
|
}
|
||||||
|
size="sm"
|
||||||
|
onClick={() => {
|
||||||
|
const updatedSources = [
|
||||||
|
...selectedDataCenter.dataCenterEmissionSources,
|
||||||
|
];
|
||||||
|
// First, set all sources to not default
|
||||||
|
updatedSources.forEach(
|
||||||
|
(s) => (s.isDefault = false)
|
||||||
|
);
|
||||||
|
// Then set the selected one as default
|
||||||
|
updatedSources[index].isDefault = true;
|
||||||
|
setSelectedDataCenter({
|
||||||
|
...selectedDataCenter,
|
||||||
|
dataCenterEmissionSources: updatedSources,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
title="Set as default emission source"
|
||||||
|
>
|
||||||
|
{source.isDefault ? "★ Default" : "☆ Default"}
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
color="outline-danger"
|
||||||
|
size="sm"
|
||||||
|
onClick={() => {
|
||||||
|
const updatedSources =
|
||||||
|
selectedDataCenter.dataCenterEmissionSources.filter(
|
||||||
|
(_, i) => i !== index
|
||||||
|
);
|
||||||
|
// If we're removing the default source and there are other sources, make the first one default
|
||||||
|
if (
|
||||||
|
source.isDefault &&
|
||||||
|
updatedSources.length > 0
|
||||||
|
) {
|
||||||
|
updatedSources[0].isDefault = true;
|
||||||
|
}
|
||||||
|
setSelectedDataCenter({
|
||||||
|
...selectedDataCenter,
|
||||||
|
dataCenterEmissionSources: updatedSources,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
disabled={
|
||||||
|
selectedDataCenter.dataCenterEmissionSources
|
||||||
|
.length === 1
|
||||||
|
}
|
||||||
|
title="Remove emission source"
|
||||||
|
>
|
||||||
|
<Trash size={14} />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
)
|
||||||
)}
|
)}
|
||||||
onChange={(option) => {
|
<Button
|
||||||
setSelectedDataCenter({
|
color="primary"
|
||||||
...selectedDataCenter,
|
size="sm"
|
||||||
emissionSourceId: option?.value,
|
onClick={() => {
|
||||||
consuptionUnitId: null,
|
setSelectedDataCenter({
|
||||||
});
|
...selectedDataCenter,
|
||||||
}}
|
dataCenterEmissionSources: [
|
||||||
isClearable
|
...selectedDataCenter.dataCenterEmissionSources,
|
||||||
filterOption={customFilterForSelect}
|
{
|
||||||
isDisabled={!selectedDataCenter.subSectorId}
|
emissionSourceId: null,
|
||||||
/>
|
consuptionUnitId: null,
|
||||||
</FormGroup>
|
isDefault: false,
|
||||||
</Col>
|
},
|
||||||
<Col sm="6">
|
],
|
||||||
<FormGroup>
|
});
|
||||||
<Label for="consuptionUnit">Consumption Unit</Label>
|
}}
|
||||||
<Select
|
disabled={!selectedDataCenter.subSectorId}
|
||||||
id="consuptionUnit"
|
>
|
||||||
name="consuptionUnit"
|
<Plus size={14} className="me-1" />
|
||||||
placeholder="Select consumption unit"
|
Add Emission Source
|
||||||
options={consuptionUnitsOptions}
|
</Button>
|
||||||
value={consuptionUnitsOptions?.find(
|
</div>
|
||||||
(option) => option.value === selectedDataCenter.consuptionUnitId
|
|
||||||
)}
|
|
||||||
onChange={(option) => {
|
|
||||||
setSelectedDataCenter({
|
|
||||||
...selectedDataCenter,
|
|
||||||
consuptionUnitId: option?.value,
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
isClearable
|
|
||||||
filterOption={customFilterForSelect}
|
|
||||||
isDisabled={!selectedDataCenter.emissionSourceId}
|
|
||||||
/>
|
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
</Col>
|
</Col>
|
||||||
<Col sm="12">
|
<Col sm="12">
|
||||||
@@ -951,7 +1222,8 @@ const DataCenterManagement = () => {
|
|||||||
placeholder="Select activity sub unit"
|
placeholder="Select activity sub unit"
|
||||||
options={activitySubUnitsOptions}
|
options={activitySubUnitsOptions}
|
||||||
value={activitySubUnitsOptions?.find(
|
value={activitySubUnitsOptions?.find(
|
||||||
(option) => option.value === selectedDataCenter.activitySubUnitId
|
(option) =>
|
||||||
|
option.value === selectedDataCenter.activitySubUnitId
|
||||||
)}
|
)}
|
||||||
onChange={(option) => {
|
onChange={(option) => {
|
||||||
setSelectedDataCenter({
|
setSelectedDataCenter({
|
||||||
@@ -965,7 +1237,7 @@ const DataCenterManagement = () => {
|
|||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
</Col>
|
</Col>
|
||||||
|
|
||||||
<Col sm="12">
|
<Col sm="12">
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<Label>{t("DataCenter.location")}</Label>
|
<Label>{t("DataCenter.location")}</Label>
|
||||||
@@ -986,7 +1258,7 @@ const DataCenterManagement = () => {
|
|||||||
setSelectedDataCenter({
|
setSelectedDataCenter({
|
||||||
...selectedDataCenter,
|
...selectedDataCenter,
|
||||||
latitude: pos[0],
|
latitude: pos[0],
|
||||||
longitude: pos[1]
|
longitude: pos[1],
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
setSelectedDataCenter={setSelectedDataCenter}
|
setSelectedDataCenter={setSelectedDataCenter}
|
||||||
@@ -1002,14 +1274,13 @@ const DataCenterManagement = () => {
|
|||||||
<Button
|
<Button
|
||||||
color="primary"
|
color="primary"
|
||||||
onClick={handleSubmit}
|
onClick={handleSubmit}
|
||||||
disabled={!selectedDataCenter.name || !selectedDataCenter.externalId}
|
disabled={
|
||||||
|
!selectedDataCenter.name || !selectedDataCenter.externalId
|
||||||
|
}
|
||||||
>
|
>
|
||||||
{t("Common.save")}
|
{t("Common.save")}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button color="secondary" onClick={handleCloseModal}>
|
||||||
color="secondary"
|
|
||||||
onClick={handleCloseModal}
|
|
||||||
>
|
|
||||||
{t("Common.cancel")}
|
{t("Common.cancel")}
|
||||||
</Button>
|
</Button>
|
||||||
</ModalFooter>
|
</ModalFooter>
|
||||||
@@ -1083,9 +1354,7 @@ const DataCenterManagement = () => {
|
|||||||
progressPending={dataCenterStore?.loading}
|
progressPending={dataCenterStore?.loading}
|
||||||
progressComponent={<div className="text-center p-3">Loading...</div>}
|
progressComponent={<div className="text-center p-3">Loading...</div>}
|
||||||
noDataComponent={
|
noDataComponent={
|
||||||
<div className="p-2 text-center">
|
<div className="p-2 text-center">{t("Common.noDataAvailable")}</div>
|
||||||
{t("Common.noDataAvailable")}
|
|
||||||
</div>
|
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -1094,4 +1363,4 @@ const DataCenterManagement = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default memo(DataCenterManagement);
|
export default memo(DataCenterManagement);
|
||||||
|
|||||||
Reference in New Issue
Block a user