Loading capif_frontend/package.json +1 −0 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ "@reduxjs/toolkit": "1.9.5", "@tanstack/react-query": "^5.8.9", "aes-js": "^3.1.2", "ajv": "^8.17.1", "apexcharts-clevision": "3.28.5", "axios": "1.4.0", "axios-mock-adapter": "1.21.4", Loading capif_frontend/src/components/ConfigCapif.js 0 → 100644 +271 −0 Original line number Diff line number Diff line import React, { useEffect, useState } from 'react'; import { useQuery, useMutation } from '@tanstack/react-query'; import { getConfiguration, updateConfigParam, replaceConfiguration } from 'src/configs/apiService'; import { Grid, Card, Typography, CardHeader, CardContent, TextField, Button, Accordion, AccordionSummary, AccordionDetails, Box } from '@mui/material'; import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; import Ajv from 'ajv'; const ajv = new Ajv(); // Esquema de validación para la configuración const configSchema = { type: "object", properties: { config_name: { type: "string" }, version: { type: "string" }, description: { type: "string" }, settings: { type: "object", properties: { ttl_superadmin_cert: { type: "string" }, ttl_invoker_cert: { type: "string" }, ttl_provider_cert: { type: "string" }, security_method_priority: { type: "object", properties: { oauth: { type: "number" }, pki: { type: "number" }, psk: { type: "number" } }, required: ["oauth", "pki", "psk"] }, acl_policy_settings: { type: "object", properties: { allowedTotalInvocations: { type: "number" }, allowedInvocationsPerSecond: { type: "number" }, allowedInvocationTimeRangeDays: { type: "number" } }, required: ["allowedTotalInvocations", "allowedInvocationsPerSecond", "allowedInvocationTimeRangeDays"] } }, required: ["ttl_superadmin_cert", "ttl_invoker_cert", "ttl_provider_cert", "security_method_priority", "acl_policy_settings"] } }, required: ["config_name", "version", "description", "settings"] }; const ConfigCapif = () => { // Obtener configuración desde el backend const { data: configData, isLoading, isError, refetch } = useQuery({ queryKey: ['configuration'], queryFn: getConfiguration, }); const [editableConfig, setEditableConfig] = useState(null); const [jsonConfig, setJsonConfig] = useState(''); const [isJsonValid, setIsJsonValid] = useState(true); useEffect(() => { if (configData) { setEditableConfig(configData); } }, [configData]); // Mutaciones para actualizar parámetros individuales y reemplazar la configuración const updateParamMutation = useMutation({ mutationFn: updateConfigParam, onSuccess: () => refetch(), }); const replaceConfigMutation = useMutation({ mutationFn: replaceConfiguration, onSuccess: () => refetch(), }); const handleValueChange = (path, value) => { setEditableConfig((prev) => { const newConfig = { ...prev }; const keys = path.split('.'); let current = newConfig; for (let i = 0; i < keys.length - 1; i++) { current = current[keys[i]]; } current[keys[keys.length - 1]] = value; return { ...newConfig }; }); }; const handleBlur = (path, value) => { updateParamMutation.mutate({ param_path: path, new_value: value }); }; const handleJsonChange = (e) => { const value = e.target.value; setJsonConfig(value); try { const parsedJson = JSON.parse(value); const validate = ajv.compile(configSchema); setIsJsonValid(validate(parsedJson)); } catch (error) { setIsJsonValid(false); } }; const handleJsonSubmit = () => { try { const parsedJson = JSON.parse(jsonConfig); const validate = ajv.compile(configSchema); const valid = validate(parsedJson); if (!valid) { setIsJsonValid(false); console.error("Errores de validación:", validate.errors); alert("JSON inválido: No cumple con la estructura requerida."); return; } setIsJsonValid(true); replaceConfigMutation.mutate(parsedJson); } catch (error) { setIsJsonValid(false); alert("Formato de JSON inválido"); } }; if (isLoading) return <Typography>Loading...</Typography>; if (isError) return <Typography>Error loading configuration</Typography>; return ( <Grid container spacing={3} marginTop={2}> {/* Cuadro principal con datos generales y secciones desplegables */} <Grid item xs={12}> <Card> <CardHeader title="General Configuration" /> <CardContent> {/* General Configuration */} <Box display="flex" alignItems="center" mb={2}> <Typography variant="subtitle1" sx={{ flex: 1 }}>Configuration Name</Typography> <TextField sx={{ width: '700px' }} value={editableConfig?.configuration_name || ''} onChange={(e) => handleValueChange('configuration_name', e.target.value)} onBlur={(e) => handleBlur('configuration_name', e.target.value)} /> </Box> <Box display="flex" alignItems="center" mb={2}> <Typography variant="subtitle1" sx={{ flex: 1 }}>Description</Typography> <TextField sx={{ width: '700px' }} value={editableConfig?.description || ''} onChange={(e) => handleValueChange('description', e.target.value)} onBlur={(e) => handleBlur('description', e.target.value)} /> </Box> <Box display="flex" alignItems="center" mb={2}> <Typography variant="subtitle1" sx={{ flex: 1 }}>Version</Typography> <TextField sx={{ width: '700px' }} value={editableConfig?.version || ''} onChange={(e) => handleValueChange('version', e.target.value)} onBlur={(e) => handleBlur('version', e.target.value)} /> </Box> {/* ACL Policy Settings */} <Accordion disableGutters> <AccordionSummary expandIcon={<ExpandMoreIcon />}> <Typography variant="h6">ACL Policy Settings</Typography> </AccordionSummary> <AccordionDetails> {editableConfig?.settings?.acl_policy_settings && Object.entries(editableConfig.settings.acl_policy_settings).map(([key, value]) => ( <Box key={key} display="flex" alignItems="center" mb={1}> <Typography variant="subtitle1" sx={{ flex: 1 }}>{key}</Typography> <TextField sx={{ width: '700px' }} value={String(value)} onChange={(e) => handleValueChange(`settings.acl_policy_settings.${key}`, e.target.value)} onBlur={(e) => handleBlur(`settings.acl_policy_settings.${key}`, e.target.value)} /> </Box> )) } </AccordionDetails> </Accordion> {/* Security Method Priority */} <Accordion disableGutters> <AccordionSummary expandIcon={<ExpandMoreIcon />}> <Typography variant="h6">Security Method Priority</Typography> </AccordionSummary> <AccordionDetails> {editableConfig?.settings?.security_method_priority && Object.entries(editableConfig.settings.security_method_priority).map(([key, value]) => ( <Box key={key} display="flex" alignItems="center" mb={1}> <Typography variant="subtitle1" sx={{ flex: 1 }}>{key}</Typography> <TextField sx={{ width: '700px' }} value={String(value)} onChange={(e) => handleValueChange(`settings.security_method_priority.${key}`, e.target.value)} onBlur={(e) => handleBlur(`settings.security_method_priority.${key}`, e.target.value)} /> </Box> )) } </AccordionDetails> </Accordion> {/* Certificate Expiration Period */} <Accordion disableGutters> <AccordionSummary expandIcon={<ExpandMoreIcon />}> <Typography variant="h6">Certificate Expiration Period</Typography> </AccordionSummary> <AccordionDetails> {['ttl_invoker_cert', 'ttl_provider_cert', 'ttl_superadmin_cert'].map((key) => ( <Box key={key} display="flex" alignItems="center" mb={1}> <Typography variant="subtitle1" sx={{ flex: 1 }}>{key.replace('_', ' ')}</Typography> <TextField sx={{ width: '700px' }} value={editableConfig?.settings?.[key] || ''} onChange={(e) => handleValueChange(`settings.${key}`, e.target.value)} onBlur={(e) => handleBlur(`settings.${key}`, e.target.value)} /> </Box> ))} </AccordionDetails> </Accordion> </CardContent> </Card> </Grid> {/* Upload JSON Configuration */} <Grid item xs={12}> <Card> <CardHeader title="Upload New Configuration" /> <CardContent> <TextField fullWidth label="Paste JSON here" multiline rows={8} variant="outlined" value={jsonConfig} onChange={handleJsonChange} error={!isJsonValid} helperText={!isJsonValid ? "Invalid JSON format" : ""} /> <Button variant="contained" fullWidth sx={{ mt: 2 }} onClick={handleJsonSubmit} disabled={!isJsonValid}> Replace Configuration </Button> </CardContent> </Card> </Grid> </Grid> ); }; export default ConfigCapif; capif_frontend/src/components/ConfigRegister.js 0 → 100644 +22 −0 Original line number Diff line number Diff line import React from 'react'; import { Card, CardHeader, CardContent, TextField, Button, Typography, Box } from '@mui/material'; const RegisterApplication = () => { return ( <Box p={3}> <Typography variant="h6">Register Application</Typography> <Card> <CardHeader title="New Application Registration" /> <CardContent> <TextField fullWidth label="Application Name" variant="outlined" /> <TextField fullWidth label="Owner" variant="outlined" sx={{ mt: 2 }} /> <TextField fullWidth label="Description" multiline rows={4} variant="outlined" sx={{ mt: 2 }} /> <Button variant="contained" fullWidth sx={{ mt: 2 }}>Register</Button> </CardContent> </Card> </Box> ); }; export default RegisterApplication; capif_frontend/src/pages/configuration/index.js +21 −66 Original line number Diff line number Diff line Loading @@ -9,7 +9,12 @@ import { CardContent, TextField, Button, Tabs, Tab, Box } from '@mui/material'; import ConfigCapif from 'src/components/ConfigCapif'; import ConfigRegister from 'src/components/ConfigRegister'; const Configuration = () => { // Obtener configuración desde el backend Loading @@ -20,6 +25,7 @@ const Configuration = () => { const [editableConfig, setEditableConfig] = useState(null); const [jsonConfig, setJsonConfig] = useState(''); const [selectedTab, setSelectedTab] = useState(0); // Estado para las pestañas useEffect(() => { if (configData) { Loading Loading @@ -64,78 +70,27 @@ const Configuration = () => { } }; const handleTabChange = (event, newValue) => { setSelectedTab(newValue); }; if (isLoading) return <Typography>Loading...</Typography>; if (isError) return <Typography>Error loading configuration</Typography>; return ( <Grid container spacing={3}> {/* General Info */} <Grid item xs={12} md={4}> <Card> <CardHeader title="General Configuration" /> <CardContent> <Typography variant="subtitle1">Configuration Name</Typography> <TextField fullWidth value={editableConfig?.configuration_name || ''} onChange={(e) => handleValueChange('configuration_name', e.target.value)} onBlur={(e) => handleBlur('configuration_name', e.target.value)} /> <Typography variant="subtitle1">Description</Typography> <TextField fullWidth value={editableConfig?.description || ''} onChange={(e) => handleValueChange('description', e.target.value)} onBlur={(e) => handleBlur('description', e.target.value)} /> <Typography variant="subtitle1">Version</Typography> <TextField fullWidth value={editableConfig?.version || ''} onChange={(e) => handleValueChange('version', e.target.value)} onBlur={(e) => handleBlur('version', e.target.value)} /> </CardContent> </Card> </Grid> {/* ACL Policy Settings */} <Grid item xs={12} md={4}> <Card> <CardHeader title="ACL Policy Settings" /> <CardContent> {editableConfig?.settings?.acl_policy_settings && Object.entries(editableConfig.settings.acl_policy_settings).map(([key, value]) => ( <div key={key}> <Typography variant="subtitle1">{key}</Typography> <TextField fullWidth value={String(value)} onChange={(e) => handleValueChange(`settings.acl_policy_settings.${key}`, e.target.value)} onBlur={(e) => handleBlur(`settings.acl_policy_settings.${key}`, e.target.value)} /> </div> ))} </CardContent> </Card> </Grid> {/* Security Method Priority */} <Grid item xs={12} md={4}> <Card> <CardHeader title="Security Method Priority" /> <CardContent> {editableConfig?.settings?.security_method_priority && Object.entries(editableConfig.settings.security_method_priority).map(([key, value]) => ( <div key={key}> <Typography variant="subtitle1">{key}</Typography> <TextField fullWidth value={String(value)} onChange={(e) => handleValueChange(`settings.security_method_priority.${key}`, e.target.value)} onBlur={(e) => handleBlur(`settings.security_method_priority.${key}`, e.target.value)} /> </div> ))} </CardContent> </Card> </Grid> <Box> {/* Barra de Tabs */} <Tabs value={selectedTab} onChange={handleTabChange} variant="fullWidth"> <Tab label="Capif Configuration" /> <Tab label="Register Configuration" /> </Tabs> {/* Certify Expiration Period */} <Grid item xs={12} md={4}> <Card> <CardHeader title="Certify Expiration Period" /> <CardContent> <Typography variant="subtitle1">certify_expiration_period</Typography> <TextField fullWidth value={String(editableConfig?.settings?.certify_expiration_period || '')} onChange={(e) => handleValueChange('settings.certify_expiration_period', e.target.value)} onBlur={(e) => handleBlur('settings.certify_expiration_period', e.target.value)} /> </CardContent> </Card> </Grid> {/* CConfiguración de Capif*/} {selectedTab === 0 && <ConfigCapif />} {/* Upload JSON Configuration */} <Grid item xs={12}> <Card> <CardHeader title="Upload New Configuration" /> <CardContent> <TextField fullWidth label="Paste JSON here" multiline rows={8} variant="outlined" value={jsonConfig} onChange={(e) => setJsonConfig(e.target.value)} /> <Button variant="contained" fullWidth onClick={handleJsonSubmit} disabled={replaceConfigMutation.isLoading}>{replaceConfigMutation.isLoading ? 'Updating...' : 'Replace Configuration'}</Button> </CardContent> </Card> </Grid> </Grid> {/* Configuración del Register */} {selectedTab === 1 && <ConfigRegister />} </Box> ); }; Loading capif_frontend/yarn.lock +0 −0 File changed.Preview suppressed by a .gitattributes entry or the file's encoding is unsupported. View original file View changed file Loading
capif_frontend/package.json +1 −0 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ "@reduxjs/toolkit": "1.9.5", "@tanstack/react-query": "^5.8.9", "aes-js": "^3.1.2", "ajv": "^8.17.1", "apexcharts-clevision": "3.28.5", "axios": "1.4.0", "axios-mock-adapter": "1.21.4", Loading
capif_frontend/src/components/ConfigCapif.js 0 → 100644 +271 −0 Original line number Diff line number Diff line import React, { useEffect, useState } from 'react'; import { useQuery, useMutation } from '@tanstack/react-query'; import { getConfiguration, updateConfigParam, replaceConfiguration } from 'src/configs/apiService'; import { Grid, Card, Typography, CardHeader, CardContent, TextField, Button, Accordion, AccordionSummary, AccordionDetails, Box } from '@mui/material'; import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; import Ajv from 'ajv'; const ajv = new Ajv(); // Esquema de validación para la configuración const configSchema = { type: "object", properties: { config_name: { type: "string" }, version: { type: "string" }, description: { type: "string" }, settings: { type: "object", properties: { ttl_superadmin_cert: { type: "string" }, ttl_invoker_cert: { type: "string" }, ttl_provider_cert: { type: "string" }, security_method_priority: { type: "object", properties: { oauth: { type: "number" }, pki: { type: "number" }, psk: { type: "number" } }, required: ["oauth", "pki", "psk"] }, acl_policy_settings: { type: "object", properties: { allowedTotalInvocations: { type: "number" }, allowedInvocationsPerSecond: { type: "number" }, allowedInvocationTimeRangeDays: { type: "number" } }, required: ["allowedTotalInvocations", "allowedInvocationsPerSecond", "allowedInvocationTimeRangeDays"] } }, required: ["ttl_superadmin_cert", "ttl_invoker_cert", "ttl_provider_cert", "security_method_priority", "acl_policy_settings"] } }, required: ["config_name", "version", "description", "settings"] }; const ConfigCapif = () => { // Obtener configuración desde el backend const { data: configData, isLoading, isError, refetch } = useQuery({ queryKey: ['configuration'], queryFn: getConfiguration, }); const [editableConfig, setEditableConfig] = useState(null); const [jsonConfig, setJsonConfig] = useState(''); const [isJsonValid, setIsJsonValid] = useState(true); useEffect(() => { if (configData) { setEditableConfig(configData); } }, [configData]); // Mutaciones para actualizar parámetros individuales y reemplazar la configuración const updateParamMutation = useMutation({ mutationFn: updateConfigParam, onSuccess: () => refetch(), }); const replaceConfigMutation = useMutation({ mutationFn: replaceConfiguration, onSuccess: () => refetch(), }); const handleValueChange = (path, value) => { setEditableConfig((prev) => { const newConfig = { ...prev }; const keys = path.split('.'); let current = newConfig; for (let i = 0; i < keys.length - 1; i++) { current = current[keys[i]]; } current[keys[keys.length - 1]] = value; return { ...newConfig }; }); }; const handleBlur = (path, value) => { updateParamMutation.mutate({ param_path: path, new_value: value }); }; const handleJsonChange = (e) => { const value = e.target.value; setJsonConfig(value); try { const parsedJson = JSON.parse(value); const validate = ajv.compile(configSchema); setIsJsonValid(validate(parsedJson)); } catch (error) { setIsJsonValid(false); } }; const handleJsonSubmit = () => { try { const parsedJson = JSON.parse(jsonConfig); const validate = ajv.compile(configSchema); const valid = validate(parsedJson); if (!valid) { setIsJsonValid(false); console.error("Errores de validación:", validate.errors); alert("JSON inválido: No cumple con la estructura requerida."); return; } setIsJsonValid(true); replaceConfigMutation.mutate(parsedJson); } catch (error) { setIsJsonValid(false); alert("Formato de JSON inválido"); } }; if (isLoading) return <Typography>Loading...</Typography>; if (isError) return <Typography>Error loading configuration</Typography>; return ( <Grid container spacing={3} marginTop={2}> {/* Cuadro principal con datos generales y secciones desplegables */} <Grid item xs={12}> <Card> <CardHeader title="General Configuration" /> <CardContent> {/* General Configuration */} <Box display="flex" alignItems="center" mb={2}> <Typography variant="subtitle1" sx={{ flex: 1 }}>Configuration Name</Typography> <TextField sx={{ width: '700px' }} value={editableConfig?.configuration_name || ''} onChange={(e) => handleValueChange('configuration_name', e.target.value)} onBlur={(e) => handleBlur('configuration_name', e.target.value)} /> </Box> <Box display="flex" alignItems="center" mb={2}> <Typography variant="subtitle1" sx={{ flex: 1 }}>Description</Typography> <TextField sx={{ width: '700px' }} value={editableConfig?.description || ''} onChange={(e) => handleValueChange('description', e.target.value)} onBlur={(e) => handleBlur('description', e.target.value)} /> </Box> <Box display="flex" alignItems="center" mb={2}> <Typography variant="subtitle1" sx={{ flex: 1 }}>Version</Typography> <TextField sx={{ width: '700px' }} value={editableConfig?.version || ''} onChange={(e) => handleValueChange('version', e.target.value)} onBlur={(e) => handleBlur('version', e.target.value)} /> </Box> {/* ACL Policy Settings */} <Accordion disableGutters> <AccordionSummary expandIcon={<ExpandMoreIcon />}> <Typography variant="h6">ACL Policy Settings</Typography> </AccordionSummary> <AccordionDetails> {editableConfig?.settings?.acl_policy_settings && Object.entries(editableConfig.settings.acl_policy_settings).map(([key, value]) => ( <Box key={key} display="flex" alignItems="center" mb={1}> <Typography variant="subtitle1" sx={{ flex: 1 }}>{key}</Typography> <TextField sx={{ width: '700px' }} value={String(value)} onChange={(e) => handleValueChange(`settings.acl_policy_settings.${key}`, e.target.value)} onBlur={(e) => handleBlur(`settings.acl_policy_settings.${key}`, e.target.value)} /> </Box> )) } </AccordionDetails> </Accordion> {/* Security Method Priority */} <Accordion disableGutters> <AccordionSummary expandIcon={<ExpandMoreIcon />}> <Typography variant="h6">Security Method Priority</Typography> </AccordionSummary> <AccordionDetails> {editableConfig?.settings?.security_method_priority && Object.entries(editableConfig.settings.security_method_priority).map(([key, value]) => ( <Box key={key} display="flex" alignItems="center" mb={1}> <Typography variant="subtitle1" sx={{ flex: 1 }}>{key}</Typography> <TextField sx={{ width: '700px' }} value={String(value)} onChange={(e) => handleValueChange(`settings.security_method_priority.${key}`, e.target.value)} onBlur={(e) => handleBlur(`settings.security_method_priority.${key}`, e.target.value)} /> </Box> )) } </AccordionDetails> </Accordion> {/* Certificate Expiration Period */} <Accordion disableGutters> <AccordionSummary expandIcon={<ExpandMoreIcon />}> <Typography variant="h6">Certificate Expiration Period</Typography> </AccordionSummary> <AccordionDetails> {['ttl_invoker_cert', 'ttl_provider_cert', 'ttl_superadmin_cert'].map((key) => ( <Box key={key} display="flex" alignItems="center" mb={1}> <Typography variant="subtitle1" sx={{ flex: 1 }}>{key.replace('_', ' ')}</Typography> <TextField sx={{ width: '700px' }} value={editableConfig?.settings?.[key] || ''} onChange={(e) => handleValueChange(`settings.${key}`, e.target.value)} onBlur={(e) => handleBlur(`settings.${key}`, e.target.value)} /> </Box> ))} </AccordionDetails> </Accordion> </CardContent> </Card> </Grid> {/* Upload JSON Configuration */} <Grid item xs={12}> <Card> <CardHeader title="Upload New Configuration" /> <CardContent> <TextField fullWidth label="Paste JSON here" multiline rows={8} variant="outlined" value={jsonConfig} onChange={handleJsonChange} error={!isJsonValid} helperText={!isJsonValid ? "Invalid JSON format" : ""} /> <Button variant="contained" fullWidth sx={{ mt: 2 }} onClick={handleJsonSubmit} disabled={!isJsonValid}> Replace Configuration </Button> </CardContent> </Card> </Grid> </Grid> ); }; export default ConfigCapif;
capif_frontend/src/components/ConfigRegister.js 0 → 100644 +22 −0 Original line number Diff line number Diff line import React from 'react'; import { Card, CardHeader, CardContent, TextField, Button, Typography, Box } from '@mui/material'; const RegisterApplication = () => { return ( <Box p={3}> <Typography variant="h6">Register Application</Typography> <Card> <CardHeader title="New Application Registration" /> <CardContent> <TextField fullWidth label="Application Name" variant="outlined" /> <TextField fullWidth label="Owner" variant="outlined" sx={{ mt: 2 }} /> <TextField fullWidth label="Description" multiline rows={4} variant="outlined" sx={{ mt: 2 }} /> <Button variant="contained" fullWidth sx={{ mt: 2 }}>Register</Button> </CardContent> </Card> </Box> ); }; export default RegisterApplication;
capif_frontend/src/pages/configuration/index.js +21 −66 Original line number Diff line number Diff line Loading @@ -9,7 +9,12 @@ import { CardContent, TextField, Button, Tabs, Tab, Box } from '@mui/material'; import ConfigCapif from 'src/components/ConfigCapif'; import ConfigRegister from 'src/components/ConfigRegister'; const Configuration = () => { // Obtener configuración desde el backend Loading @@ -20,6 +25,7 @@ const Configuration = () => { const [editableConfig, setEditableConfig] = useState(null); const [jsonConfig, setJsonConfig] = useState(''); const [selectedTab, setSelectedTab] = useState(0); // Estado para las pestañas useEffect(() => { if (configData) { Loading Loading @@ -64,78 +70,27 @@ const Configuration = () => { } }; const handleTabChange = (event, newValue) => { setSelectedTab(newValue); }; if (isLoading) return <Typography>Loading...</Typography>; if (isError) return <Typography>Error loading configuration</Typography>; return ( <Grid container spacing={3}> {/* General Info */} <Grid item xs={12} md={4}> <Card> <CardHeader title="General Configuration" /> <CardContent> <Typography variant="subtitle1">Configuration Name</Typography> <TextField fullWidth value={editableConfig?.configuration_name || ''} onChange={(e) => handleValueChange('configuration_name', e.target.value)} onBlur={(e) => handleBlur('configuration_name', e.target.value)} /> <Typography variant="subtitle1">Description</Typography> <TextField fullWidth value={editableConfig?.description || ''} onChange={(e) => handleValueChange('description', e.target.value)} onBlur={(e) => handleBlur('description', e.target.value)} /> <Typography variant="subtitle1">Version</Typography> <TextField fullWidth value={editableConfig?.version || ''} onChange={(e) => handleValueChange('version', e.target.value)} onBlur={(e) => handleBlur('version', e.target.value)} /> </CardContent> </Card> </Grid> {/* ACL Policy Settings */} <Grid item xs={12} md={4}> <Card> <CardHeader title="ACL Policy Settings" /> <CardContent> {editableConfig?.settings?.acl_policy_settings && Object.entries(editableConfig.settings.acl_policy_settings).map(([key, value]) => ( <div key={key}> <Typography variant="subtitle1">{key}</Typography> <TextField fullWidth value={String(value)} onChange={(e) => handleValueChange(`settings.acl_policy_settings.${key}`, e.target.value)} onBlur={(e) => handleBlur(`settings.acl_policy_settings.${key}`, e.target.value)} /> </div> ))} </CardContent> </Card> </Grid> {/* Security Method Priority */} <Grid item xs={12} md={4}> <Card> <CardHeader title="Security Method Priority" /> <CardContent> {editableConfig?.settings?.security_method_priority && Object.entries(editableConfig.settings.security_method_priority).map(([key, value]) => ( <div key={key}> <Typography variant="subtitle1">{key}</Typography> <TextField fullWidth value={String(value)} onChange={(e) => handleValueChange(`settings.security_method_priority.${key}`, e.target.value)} onBlur={(e) => handleBlur(`settings.security_method_priority.${key}`, e.target.value)} /> </div> ))} </CardContent> </Card> </Grid> <Box> {/* Barra de Tabs */} <Tabs value={selectedTab} onChange={handleTabChange} variant="fullWidth"> <Tab label="Capif Configuration" /> <Tab label="Register Configuration" /> </Tabs> {/* Certify Expiration Period */} <Grid item xs={12} md={4}> <Card> <CardHeader title="Certify Expiration Period" /> <CardContent> <Typography variant="subtitle1">certify_expiration_period</Typography> <TextField fullWidth value={String(editableConfig?.settings?.certify_expiration_period || '')} onChange={(e) => handleValueChange('settings.certify_expiration_period', e.target.value)} onBlur={(e) => handleBlur('settings.certify_expiration_period', e.target.value)} /> </CardContent> </Card> </Grid> {/* CConfiguración de Capif*/} {selectedTab === 0 && <ConfigCapif />} {/* Upload JSON Configuration */} <Grid item xs={12}> <Card> <CardHeader title="Upload New Configuration" /> <CardContent> <TextField fullWidth label="Paste JSON here" multiline rows={8} variant="outlined" value={jsonConfig} onChange={(e) => setJsonConfig(e.target.value)} /> <Button variant="contained" fullWidth onClick={handleJsonSubmit} disabled={replaceConfigMutation.isLoading}>{replaceConfigMutation.isLoading ? 'Updating...' : 'Replace Configuration'}</Button> </CardContent> </Card> </Grid> </Grid> {/* Configuración del Register */} {selectedTab === 1 && <ConfigRegister />} </Box> ); }; Loading
capif_frontend/yarn.lock +0 −0 File changed.Preview suppressed by a .gitattributes entry or the file's encoding is unsupported. View original file View changed file