fixed issue GUI and Datacenter tab related

This commit is contained in:
2025-08-07 19:28:56 +03:00
parent 5c0b325005
commit 39fffadbd2
14 changed files with 686 additions and 188 deletions

View File

@@ -28,7 +28,8 @@ import { Edit } from "@mui/icons-material";
import { useSnackbar } from "notistack";
import { default as SweetAlert } from "sweetalert2";
import withReactContent from "sweetalert2-react-content";
import { getDataCenters, createDataCenter, updateDataCenter, deleteDataCenter } from "../redux/actions/dataCenter";
import { getDataCenters, createDataCenter, updateDataCenter, deleteDataCenter, getEmissionScopes } from "../redux/actions/dataCenter";
import { getAreas, getAreasWithCriteria } from "../redux/actions/areas";
import { useTranslation } from "react-i18next";
import { getSectors, getSectorById, getSubSectorById, getConsuptionUnits } from "../redux/actions/datas";
import { getAllEmissionSources } from "../redux/actions/emissionSources";
@@ -105,6 +106,8 @@ const DataCenterManagement = () => {
externalId: "",
number: "",
address: "",
areaId: null,
cityId: null,
latitude: null,
longitude: null,
ayposURL: "",
@@ -120,14 +123,18 @@ const DataCenterManagement = () => {
const [mapPosition, setMapPosition] = useState(null);
const dataCenterStore = useSelector((state) => state.dataCenter);
const emissionScopeStore = useSelector((state) => state.emissionScope);
const datasStore = useSelector((state) => state.datas);
const emissionSourceStore = useSelector((state) => state.emissionSources);
const areasStore = useSelector((state) => state.areas);
const [sectorsOptions, setSectorsOptions] = useState([]);
const [subSectorsOptions, setSubSectorsOptions] = useState([]);
const [emissionSourcesOptions, setEmissionSourcesOptions] = useState([]);
const [consuptionUnitsOptions, setConsuptionUnitsOptions] = useState([]);
const [activitySubUnitsOptions, setActivitySubUnitsOptions] = useState([]);
const [emissionScopesOptions, setEmissionScopesOptions] = useState([]);
const [areasOptions, setAreasOptions] = useState([]);
const [citiesOptions, setCitiesOptions] = useState([]);
// Add state for selected sector and sub sector like in data input
const [selectedSector, setSelectedSector] = useState(null);
@@ -215,6 +222,8 @@ const DataCenterManagement = () => {
useEffect(() => {
dispatch(getDataCenters());
dispatch(getSectors());
dispatch(getAreas());
dispatch(getEmissionScopes());
}, [dispatch]);
useEffect(() => {
@@ -295,17 +304,48 @@ const DataCenterManagement = () => {
}, [datasStore?.consuptionUnits]);
useEffect(() => {
setEmissionScopesOptions([
{
label: "Şehir İçi",
value: false,
},
{
label: "Şehir Dışı",
value: true,
},
]);
}, []);
if (emissionScopeStore?.emissionScopes) {
setEmissionScopesOptions(
emissionScopeStore.emissionScopes.map((scope) => ({
value: scope.id,
label: scope.tag,
}))
);
}
}, [emissionScopeStore?.emissionScopes]);
// Set areas options when areas data is loaded
useEffect(() => {
if (areasStore?.areas) {
setAreasOptions(
areasStore.areas.map((area) => ({
value: area.id,
label: area.tag,
}))
);
}
}, [areasStore?.areas]);
// Set cities options when selected area changes
useEffect(() => {
if (selectedDataCenter.areaId && areasStore?.areas) {
const selectedArea = areasStore.areas.find(
(area) => area.id === selectedDataCenter.areaId
);
if (selectedArea?.cities) {
setCitiesOptions(
selectedArea.cities.map((city) => ({
value: city.id,
label: city.name,
}))
);
} else {
setCitiesOptions([]);
}
} else {
setCitiesOptions([]);
}
}, [selectedDataCenter.areaId, areasStore?.areas]);
const handleEditDataCenter = (row) => {
setEditingDataCenter(row);
@@ -314,10 +354,12 @@ const DataCenterManagement = () => {
externalId: row.externalId,
number: row.number,
address: row.address,
areaId: row.area?.id,
cityId: null, // City is a string in the backend, not an object
latitude: row.latitude,
longitude: row.longitude,
ayposURL: row.ayposURL,
city: row.city,
city: row.city || "",
emissionScopeId: row.emissionScope?.id,
sectorId: row.sector?.id,
subSectorId: row.subSector?.id,
@@ -364,9 +406,56 @@ const DataCenterManagement = () => {
}
};
const validateForm = () => {
const errors = [];
// Required fields
if (!selectedDataCenter.name) {
errors.push(t("DataCenter.nameRequired"));
}
if (!selectedDataCenter.externalId) {
errors.push(t("DataCenter.externalIdRequired"));
}
if (!selectedDataCenter.sectorId) {
errors.push(t("DataCenter.sectorRequired"));
}
// Validate external ID is a number
if (selectedDataCenter.externalId && isNaN(parseInt(selectedDataCenter.externalId))) {
errors.push(t("DataCenter.externalIdMustBeNumber"));
}
// Validate coordinates if either is provided
if ((selectedDataCenter.latitude && !selectedDataCenter.longitude) ||
(!selectedDataCenter.latitude && selectedDataCenter.longitude)) {
errors.push(t("DataCenter.bothCoordinatesRequired"));
}
// Validate area and city are selected together
if (selectedDataCenter.areaId && !selectedDataCenter.cityId) {
errors.push(t("DataCenter.cityRequired"));
}
// Validate sector hierarchy
if (selectedDataCenter.subSectorId && !selectedDataCenter.sectorId) {
errors.push(t("DataCenter.sectorRequired"));
}
if (selectedDataCenter.emissionSourceId && !selectedDataCenter.subSectorId) {
errors.push(t("DataCenter.subSectorRequired"));
}
if (selectedDataCenter.consuptionUnitId && !selectedDataCenter.emissionSourceId) {
errors.push(t("DataCenter.emissionSourceRequired"));
}
return errors;
};
const handleSubmit = async () => {
if (!selectedDataCenter.name || !selectedDataCenter.externalId) {
enqueueSnackbar(t("Common.fillRequiredFields"), { variant: "error" });
const validationErrors = validateForm();
if (validationErrors.length > 0) {
validationErrors.forEach(error => {
enqueueSnackbar(error, { variant: "error" });
});
return;
}
@@ -397,10 +486,20 @@ const DataCenterManagement = () => {
handleCloseModal();
} catch (error) {
console.error("Submit error:", error);
enqueueSnackbar(
error?.message || t("DataCenter.submitError"),
{ variant: "error" }
);
// Handle specific error cases
if (error.message?.includes("duplicate")) {
enqueueSnackbar(t("DataCenter.duplicateExternalId"), { variant: "error" });
} else if (error.message?.includes("permission")) {
enqueueSnackbar(t("Common.noPermission"), { variant: "error" });
} else if (error.message?.includes("not found")) {
enqueueSnackbar(t("DataCenter.resourceNotFound"), { variant: "error" });
} else {
enqueueSnackbar(
error?.message || t("DataCenter.submitError"),
{ variant: "error" }
);
}
}
};
@@ -599,19 +698,49 @@ const DataCenterManagement = () => {
</Col>
<Col sm="6">
<FormGroup>
<Label for="city">{t("DataCenter.city")}</Label>
<Input
type="text"
name="city"
id="city"
placeholder={t("DataCenter.city")}
value={selectedDataCenter.city}
onChange={(e) =>
<Label for="area">Area</Label>
<Select
id="area"
name="area"
placeholder="Select area"
options={areasOptions}
value={areasOptions?.find(
(option) => option.value === selectedDataCenter.areaId
)}
onChange={(option) => {
setSelectedDataCenter({
...selectedDataCenter,
city: e.target.value,
})
}
areaId: option?.value,
cityId: null,
city: "",
});
}}
isClearable
filterOption={customFilterForSelect}
/>
</FormGroup>
</Col>
<Col sm="6">
<FormGroup>
<Label for="city">City</Label>
<Select
id="city"
name="city"
placeholder="Select city"
options={citiesOptions}
value={citiesOptions?.find(
(option) => option.value === selectedDataCenter.cityId
)}
onChange={(option) => {
setSelectedDataCenter({
...selectedDataCenter,
cityId: option?.value,
city: option?.label || "",
});
}}
isClearable
filterOption={customFilterForSelect}
isDisabled={!selectedDataCenter.areaId}
/>
</FormGroup>
</Col>
@@ -670,7 +799,7 @@ const DataCenterManagement = () => {
</Col>
<Col sm="6">
<FormGroup>
<Label for="sector">Sector</Label>
<Label for="sector">Sector <span className="text-danger">*</span></Label>
<Select
id="sector"
name="sector"