Loading capif_frontend/src/components/ConfigCapif.js +75 −13 Original line number Diff line number Diff line Loading @@ -150,9 +150,31 @@ const ConfigCapif = () => { return "The 'settings' field must contain at least one section with settings."; } // Expresión regular para validar *snake_case* (solo minúsculas y _) const snakeCaseRegex = /^[a-z0-9_]+$/; // Función recursiva para validar nombres de los campos const validateKeys = (obj, parentKey = "") => { for (const key in obj) { if (!snakeCaseRegex.test(key)) { return `Invalid field name: "${parentKey}${key}". All fields must be in snake_case.`; } if (typeof obj[key] === "object" && obj[key] !== null) { const nestedError = validateKeys(obj[key], `${parentKey}${key}.`); if (nestedError) return nestedError; } } return null; }; // Validamos los nombres de los campos en toda la estructura const snakeCaseError = validateKeys(json); if (snakeCaseError) return snakeCaseError; return null; // No hay errores }; if (isLoading) return <Typography>Loading...</Typography>; if (isError) return <Typography>Error loading configuration</Typography>; Loading Loading @@ -305,6 +327,27 @@ const ConfigCapif = () => { }; const handleFileUpload = (event) => { const file = event.target.files[0]; if (!file) return; const reader = new FileReader(); reader.onload = (e) => { try { const text = e.target.result; const json = JSON.parse(text); setJsonConfig(JSON.stringify(json, null, 2)); setJsonError(""); } catch (error) { setJsonError("Invalid JSON file."); } }; reader.readAsText(file); }; return ( <Grid container spacing={3} marginTop={2}> {/* Cuadro principal con datos generales y secciones desplegables */} Loading Loading @@ -483,7 +526,26 @@ const ConfigCapif = () => { {/* Upload JSON Configuration */} <Grid item xs={12}> <Card> <CardHeader title="Upload New Configuration" /> <CardHeader title={ <Box display="flex" justifyContent="space-between" alignItems="center"> <Typography variant="h6">Upload New Configuration</Typography> {/* Botón para seleccionar archivo JSON alineado a la derecha */} <label htmlFor="file-upload"> <input type="file" accept=".json" style={{ display: "none" }} id="file-upload" onChange={handleFileUpload} /> <Button component="span" variant="contained"> Select JSON File </Button> </label> </Box> } /> <CardContent> <TextField fullWidth Loading capif_frontend/src/components/ConfigRegister.js +73 −13 Original line number Diff line number Diff line Loading @@ -143,6 +143,27 @@ const ConfigRegister = () => { return "The 'settings' field must contain at least one section with settings."; } // Expresión regular para validar *snake_case* (solo minúsculas y _) const snakeCaseRegex = /^[a-z0-9_]+$/; // Función recursiva para validar nombres de los campos const validateKeys = (obj, parentKey = "") => { for (const key in obj) { if (!snakeCaseRegex.test(key)) { return `Invalid field name: "${parentKey}${key}". All fields must be in snake_case.`; } if (typeof obj[key] === "object" && obj[key] !== null) { const nestedError = validateKeys(obj[key], `${parentKey}${key}.`); if (nestedError) return nestedError; } } return null; }; // Validamos los nombres de los campos en toda la estructura const snakeCaseError = validateKeys(json); if (snakeCaseError) return snakeCaseError; return null; // No hay errores }; Loading Loading @@ -300,6 +321,26 @@ const ConfigRegister = () => { }; const handleFileUpload = (event) => { const file = event.target.files[0]; if (!file) return; const reader = new FileReader(); reader.onload = (e) => { try { const text = e.target.result; const json = JSON.parse(text); setJsonConfig(JSON.stringify(json, null, 2)); setJsonError(""); } catch (error) { setJsonError("Invalid JSON file."); } }; reader.readAsText(file); }; return ( <Grid container spacing={3} marginTop={2}> {/* Cuadro principal con datos generales y secciones desplegables */} Loading Loading @@ -479,7 +520,26 @@ const ConfigRegister = () => { {/* Upload JSON Configuration */} <Grid item xs={12}> <Card> <CardHeader title="Upload New Configuration" /> <CardHeader title={ <Box display="flex" justifyContent="space-between" alignItems="center"> <Typography variant="h6">Upload New Configuration</Typography> {/* Botón para seleccionar archivo JSON alineado a la derecha */} <label htmlFor="file-upload"> <input type="file" accept=".json" style={{ display: "none" }} id="file-upload" onChange={handleFileUpload} /> <Button component="span" variant="contained"> Select JSON File </Button> </label> </Box> } /> <CardContent> <TextField fullWidth Loading Loading
capif_frontend/src/components/ConfigCapif.js +75 −13 Original line number Diff line number Diff line Loading @@ -150,9 +150,31 @@ const ConfigCapif = () => { return "The 'settings' field must contain at least one section with settings."; } // Expresión regular para validar *snake_case* (solo minúsculas y _) const snakeCaseRegex = /^[a-z0-9_]+$/; // Función recursiva para validar nombres de los campos const validateKeys = (obj, parentKey = "") => { for (const key in obj) { if (!snakeCaseRegex.test(key)) { return `Invalid field name: "${parentKey}${key}". All fields must be in snake_case.`; } if (typeof obj[key] === "object" && obj[key] !== null) { const nestedError = validateKeys(obj[key], `${parentKey}${key}.`); if (nestedError) return nestedError; } } return null; }; // Validamos los nombres de los campos en toda la estructura const snakeCaseError = validateKeys(json); if (snakeCaseError) return snakeCaseError; return null; // No hay errores }; if (isLoading) return <Typography>Loading...</Typography>; if (isError) return <Typography>Error loading configuration</Typography>; Loading Loading @@ -305,6 +327,27 @@ const ConfigCapif = () => { }; const handleFileUpload = (event) => { const file = event.target.files[0]; if (!file) return; const reader = new FileReader(); reader.onload = (e) => { try { const text = e.target.result; const json = JSON.parse(text); setJsonConfig(JSON.stringify(json, null, 2)); setJsonError(""); } catch (error) { setJsonError("Invalid JSON file."); } }; reader.readAsText(file); }; return ( <Grid container spacing={3} marginTop={2}> {/* Cuadro principal con datos generales y secciones desplegables */} Loading Loading @@ -483,7 +526,26 @@ const ConfigCapif = () => { {/* Upload JSON Configuration */} <Grid item xs={12}> <Card> <CardHeader title="Upload New Configuration" /> <CardHeader title={ <Box display="flex" justifyContent="space-between" alignItems="center"> <Typography variant="h6">Upload New Configuration</Typography> {/* Botón para seleccionar archivo JSON alineado a la derecha */} <label htmlFor="file-upload"> <input type="file" accept=".json" style={{ display: "none" }} id="file-upload" onChange={handleFileUpload} /> <Button component="span" variant="contained"> Select JSON File </Button> </label> </Box> } /> <CardContent> <TextField fullWidth Loading
capif_frontend/src/components/ConfigRegister.js +73 −13 Original line number Diff line number Diff line Loading @@ -143,6 +143,27 @@ const ConfigRegister = () => { return "The 'settings' field must contain at least one section with settings."; } // Expresión regular para validar *snake_case* (solo minúsculas y _) const snakeCaseRegex = /^[a-z0-9_]+$/; // Función recursiva para validar nombres de los campos const validateKeys = (obj, parentKey = "") => { for (const key in obj) { if (!snakeCaseRegex.test(key)) { return `Invalid field name: "${parentKey}${key}". All fields must be in snake_case.`; } if (typeof obj[key] === "object" && obj[key] !== null) { const nestedError = validateKeys(obj[key], `${parentKey}${key}.`); if (nestedError) return nestedError; } } return null; }; // Validamos los nombres de los campos en toda la estructura const snakeCaseError = validateKeys(json); if (snakeCaseError) return snakeCaseError; return null; // No hay errores }; Loading Loading @@ -300,6 +321,26 @@ const ConfigRegister = () => { }; const handleFileUpload = (event) => { const file = event.target.files[0]; if (!file) return; const reader = new FileReader(); reader.onload = (e) => { try { const text = e.target.result; const json = JSON.parse(text); setJsonConfig(JSON.stringify(json, null, 2)); setJsonError(""); } catch (error) { setJsonError("Invalid JSON file."); } }; reader.readAsText(file); }; return ( <Grid container spacing={3} marginTop={2}> {/* Cuadro principal con datos generales y secciones desplegables */} Loading Loading @@ -479,7 +520,26 @@ const ConfigRegister = () => { {/* Upload JSON Configuration */} <Grid item xs={12}> <Card> <CardHeader title="Upload New Configuration" /> <CardHeader title={ <Box display="flex" justifyContent="space-between" alignItems="center"> <Typography variant="h6">Upload New Configuration</Typography> {/* Botón para seleccionar archivo JSON alineado a la derecha */} <label htmlFor="file-upload"> <input type="file" accept=".json" style={{ display: "none" }} id="file-upload" onChange={handleFileUpload} /> <Button component="span" variant="contained"> Select JSON File </Button> </label> </Box> } /> <CardContent> <TextField fullWidth Loading