Ajout de l'interface pour selectionner des disques et modifications du coté serveur pour la sauvegarde

This commit is contained in:
Adevixxx
2025-11-28 10:12:10 +01:00
parent 913f7a9e42
commit 7edc2a71d8
7 changed files with 153 additions and 1 deletions

View File

@@ -0,0 +1,92 @@
import React from "react";
import ConfigBox from "@/Components/v1/ConfigBox/index.jsx";
import { Box, Stack, Typography } from "@mui/material";
import Checkbox from "@/Components/v1/Inputs/Checkbox/index.jsx";
import { useTheme } from "@emotion/react";
import { useTranslation } from "react-i18next";
import PropTypes from "prop-types";
const DiskSelection = ({ availableDisks, selectedDisks, onChange }) => {
const theme = useTheme();
const { t } = useTranslation();
const handleDiskChange = (event, mountpoint) => {
// Le composant Checkbox personnalisé renvoie l'event natif
const isChecked = event.target.checked;
let newSelectedDisks = [];
if (isChecked) {
newSelectedDisks = [...selectedDisks, mountpoint];
} else {
newSelectedDisks = selectedDisks.filter((disk) => disk !== mountpoint);
}
onChange(newSelectedDisks);
};
return (
<ConfigBox>
<Box>
<Typography component="h2" variant="h2">
{t("v1.infrastructure.disk_selection_title")}
</Typography>
<Typography component="p">
{t("v1.infrastructure.disk_selection_description")}
</Typography>
</Box>
<Stack gap={theme.spacing(6)}>
{(!availableDisks || availableDisks.length === 0) ? (
<Typography
variant="body2"
sx={{ fontStyle: 'italic', opacity: 0.8 }}
>
{t("v1.infrastructure.disk_selection_info")}
</Typography>
) : (
availableDisks.map((disk) => (
/* Reproduction exacte de la structure de CustomThreshold
pour garantir l'alignement parfait avec la section Alertes
*/
<Stack
key={disk.mountpoint}
direction={{ sm: "column", md: "row" }}
spacing={theme.spacing(2)}
>
<Box
sx={{
// Mêmes largeurs que dans CustomThreshold pour aligner les labels
width: { md: "45%", lg: "25%", xl: "20%" },
}}
justifyContent="flex-start"
>
<Checkbox
id={`disk-${disk.mountpoint}`}
name={disk.mountpoint}
label={disk.mountpoint}
isChecked={selectedDisks.includes(disk.mountpoint)}
onChange={(e) => handleDiskChange(e, disk.mountpoint)}
/>
</Box>
{/* Pas de deuxième Stack ici car nous n'avons pas besoin
du champ TextInput pour la sélection simple
*/}
</Stack>
))
)}
</Stack>
</ConfigBox>
);
};
DiskSelection.propTypes = {
availableDisks: PropTypes.arrayOf(
PropTypes.shape({
mountpoint: PropTypes.string.isRequired,
})
),
selectedDisks: PropTypes.arrayOf(PropTypes.string).isRequired,
onChange: PropTypes.func.isRequired,
};
export default DiskSelection;

View File

@@ -17,6 +17,7 @@ const useInfrastructureMonitorForm = () => {
temperature: false,
usage_temperature: "",
secret: "",
selectedDisks: [],
});
const onChangeForm = (name, value) => {
@@ -48,6 +49,7 @@ const useInfrastructureMonitorForm = () => {
temperature: gt.temperature !== undefined,
usage_temperature: gt.temperature !== undefined ? gt.temperature.toString() : "",
secret: "",
selectedDisks: [],
}));
}, []);
@@ -81,6 +83,7 @@ const useInfrastructureMonitorForm = () => {
? (thresholds.usage_temperature * 100).toString()
: "",
secret: monitor.secret || "",
selectedDisks: monitor.selectedDisks || [],
}));
}, []);
return {

View File

@@ -10,9 +10,11 @@ import { HttpAdornment } from "@/Components/v1/Inputs/TextInput/Adornments/index
import MonitorStatusHeader from "./Components/MonitorStatusHeader.jsx";
import MonitorActionButtons from "./Components/MonitorActionButtons.jsx";
import CustomAlertsSection from "./Components/CustomAlertsSection.jsx";
import DiskSelection from "./Components/DiskSelection.jsx";
// Utils
import NotificationsConfig from "@/Components/v1/NotificationConfig/index.jsx";
import { useGetNotificationsByTeamId } from "../../../../Hooks/v1/useNotifications.js";
import NetworkService from "../../../../Utils/NetworkService";
import { useParams } from "react-router-dom";
import { useState, useEffect } from "react";
import { useTheme } from "@emotion/react";
@@ -37,6 +39,7 @@ const CreateInfrastructureMonitor = () => {
// State
const [https, setHttps] = useState(false);
const [updateTrigger, setUpdateTrigger] = useState(false);
const [availableDisks, setAvailableDisks] = useState([]);
// Fetch monitor details if editing
const [monitor, isLoading] = useFetchHardwareMonitorById({
@@ -85,6 +88,24 @@ const CreateInfrastructureMonitor = () => {
} else if (monitor) {
setHttps(monitor.url.startsWith("https"));
initializeInfrastructureMonitorForUpdate(monitor);
const fetchLastCheck = async () => {
try {
const params = {
dateRange: "recent",
limit: 1,
sortOrder: "desc",
};
// On utilise NetworkService directement
const response = await NetworkService.get(`/api/v1/checks/${monitorId}`, { params });
const disks = response?.data?.checks?.[0]?.payload?.disks || [];
setAvailableDisks(disks);
} catch (error) {
console.error("Erreur pendant la récupération des disques:", error);
setAvailableDisks([]); // En cas d'erreur, on met un tableau vide
}
};
fetchLastCheck();
}
}, [
isCreate,
@@ -133,6 +154,15 @@ const CreateInfrastructureMonitor = () => {
isPausing ||
notificationsAreLoading;
// --- AJOUT TEMPORAIRE : Fausses données ---
const MOCK_DISKS = [
{ mountpoint: "C:" },
{ mountpoint: "D:" },
{ mountpoint: "/mnt/data" },
{ mountpoint: "/var/lib/docker" }
];
// -----------------------------------------
return (
<Box className="create-infrastructure-monitor">
<Breadcrumbs list={CRUMBS} />
@@ -327,6 +357,17 @@ const CreateInfrastructureMonitor = () => {
infrastructureMonitor={infrastructureMonitor}
handleCheckboxChange={handleCheckboxChange}
/>
{monitorId && (
<DiskSelection
availableDisks={availableDisks}
selectedDisks={infrastructureMonitor.selectedDisks}
onChange={(newSelectedDisks) =>
onChangeForm("selectedDisks", newSelectedDisks)
}
/>
)}
<ConfigBox>
<Box>
<Typography

View File

@@ -1136,5 +1136,12 @@
"packetsReceivedRate": "Packets Received Rate",
"packetsSent": "Packets Sent",
"rate": "Rate",
"selectInterface": "Select Interface"
"selectInterface": "Select Interface",
"v1": {
"infrastructure": {
"disk_selection_title": "Disk Selection",
"disk_selection_info": "No disk detected for the moment.",
"disk_selection_description": "Select the specific disks you want to monitor."
}
}
}

View File

@@ -12,6 +12,9 @@ export default defineConfig(({}) => {
return {
base: "/",
plugins: [svgr(), react()],
server: {
host: true,
},
resolve: {
alias: {
"@": path.resolve(__dirname, "src"),

View File

@@ -125,6 +125,10 @@ const MonitorSchema = mongoose.Schema(
return this.alertThreshold;
},
},
selectedDisks: {
type: [String],
default: [],
},
gameId: {
type: String,
},

View File

@@ -174,6 +174,7 @@ const createMonitorBodyValidation = joi.object({
expectedValue: joi.string().allow(""),
matchMethod: joi.string(),
gameId: joi.string().allow(""),
selectedDisks: joi.array().items(joi.string()).optional(),
group: joi.string().max(50).trim().allow(null, "").optional(),
});
@@ -204,6 +205,7 @@ const editMonitorBodyValidation = joi.object({
usage_temperature: joi.number(),
}),
gameId: joi.string(),
selectedDisks: joi.array().items(joi.string()).optional(),
group: joi.string().max(50).trim().allow(null, "").optional(),
});