Funcionando con la edicion de los esquemas
This commit is contained in:
parent
6b72069c51
commit
64a8b41881
Binary file not shown.
|
@ -1,20 +1,20 @@
|
|||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"batch_size": {
|
||||
"description": "N\u00c3\u00bamero de elementos a procesar por lote",
|
||||
"type": "number",
|
||||
"title": "Tama\u00c3\u00b1o de Lote",
|
||||
"type": "number"
|
||||
"description": "N\u00c3\u00bamero de elementos a procesar por lote"
|
||||
},
|
||||
"input_dir": {
|
||||
"description": "Ruta al directorio de archivos de entrada",
|
||||
"type": "string",
|
||||
"title": "Directorio de Entrada",
|
||||
"type": "string"
|
||||
"description": "Ruta al directorio de archivos de entrada"
|
||||
},
|
||||
"output_dir": {
|
||||
"description": "Ruta al directorio para archivos generados",
|
||||
"type": "string",
|
||||
"title": "Directorio de Salida",
|
||||
"type": "string"
|
||||
"description": "Ruta al directorio para archivos generados"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"name": "Grupo de Ejemplo",
|
||||
"description": "Scripts de demostración que muestran las funcionalidades básicas del sistema",
|
||||
"version": "1.0",
|
||||
"author": "Admin"
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"type": "object",
|
||||
"properties": {}
|
||||
}
|
|
@ -66,13 +66,36 @@ class ConfigurationManager:
|
|||
|
||||
return {"status": "success", "path": path}
|
||||
|
||||
def get_script_groups(self) -> List[str]:
|
||||
"""Returns list of available script groups."""
|
||||
return [
|
||||
d
|
||||
for d in os.listdir(self.script_groups_path)
|
||||
if os.path.isdir(os.path.join(self.script_groups_path, d))
|
||||
]
|
||||
def get_script_groups(self) -> List[Dict[str, Any]]:
|
||||
"""Returns list of available script groups with their descriptions."""
|
||||
groups = []
|
||||
for d in os.listdir(self.script_groups_path):
|
||||
group_path = os.path.join(self.script_groups_path, d)
|
||||
if os.path.isdir(group_path):
|
||||
description = self._get_group_description(group_path)
|
||||
groups.append(
|
||||
{
|
||||
"id": d,
|
||||
"name": description.get("name", d),
|
||||
"description": description.get(
|
||||
"description", "Sin descripción"
|
||||
),
|
||||
"version": description.get("version", "1.0"),
|
||||
"author": description.get("author", "Unknown"),
|
||||
}
|
||||
)
|
||||
return groups
|
||||
|
||||
def _get_group_description(self, group_path: str) -> Dict[str, Any]:
|
||||
"""Get description for a script group."""
|
||||
description_file = os.path.join(group_path, "description.json")
|
||||
try:
|
||||
if os.path.exists(description_file):
|
||||
with open(description_file, "r", encoding="utf-8") as f:
|
||||
return json.load(f)
|
||||
except Exception as e:
|
||||
print(f"Error reading group description: {e}")
|
||||
return {}
|
||||
|
||||
def get_config(self, level: str, group: str = None) -> Dict[str, Any]:
|
||||
"""Get configuration for specified level."""
|
||||
|
@ -93,27 +116,159 @@ class ConfigurationManager:
|
|||
|
||||
def get_schema(self, level: str, group: str = None) -> Dict[str, Any]:
|
||||
"""Get schema for specified level."""
|
||||
# Clean level parameter (remove -form suffix if present)
|
||||
level = level.split("-")[0]
|
||||
|
||||
try:
|
||||
# Clean level parameter
|
||||
level = str(level).split("-")[0]
|
||||
|
||||
# Determine schema path based on level
|
||||
if level == "1":
|
||||
path = os.path.join(self.data_path, "esquema.json")
|
||||
# Try esquema.json first, then schema.json if not found
|
||||
if not os.path.exists(path):
|
||||
path = os.path.join(self.data_path, "schema.json")
|
||||
elif level == "2":
|
||||
path = os.path.join(self.script_groups_path, "esquema.json")
|
||||
path = os.path.join(self.script_groups_path, group, "esquema.json")
|
||||
# Try esquema.json first, then schema.json if not found
|
||||
if not os.path.exists(path):
|
||||
path = os.path.join(self.script_groups_path, group, "schema.json")
|
||||
elif level == "3":
|
||||
if not group:
|
||||
return {} # Return empty schema if no group is specified
|
||||
return {"type": "object", "properties": {}}
|
||||
path = os.path.join(self.script_groups_path, group, "esquema.json")
|
||||
# Try esquema.json first, then schema.json if not found
|
||||
if not os.path.exists(path):
|
||||
path = os.path.join(self.script_groups_path, group, "schema.json")
|
||||
else:
|
||||
return {} # Return empty schema for invalid levels
|
||||
return {"type": "object", "properties": {}}
|
||||
|
||||
with open(path, "r") as f:
|
||||
return json.load(f)
|
||||
except FileNotFoundError:
|
||||
return {} # Return empty schema if file doesn't exist
|
||||
except json.JSONDecodeError:
|
||||
return {} # Return empty schema if file is invalid JSON
|
||||
# Read existing schema from whichever file exists
|
||||
if os.path.exists(path):
|
||||
with open(path, "r", encoding="utf-8") as f:
|
||||
schema = json.load(f)
|
||||
return (
|
||||
schema
|
||||
if isinstance(schema, dict)
|
||||
else {"type": "object", "properties": {}}
|
||||
)
|
||||
|
||||
# Create default schema if no file exists
|
||||
default_schema = {"type": "object", "properties": {}}
|
||||
os.makedirs(os.path.dirname(path), exist_ok=True)
|
||||
with open(path, "w", encoding="utf-8") as f:
|
||||
json.dump(default_schema, f, indent=2)
|
||||
return default_schema
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error loading schema: {str(e)}")
|
||||
return {"type": "object", "properties": {}}
|
||||
|
||||
def update_schema(
|
||||
self, level: str, data: Dict[str, Any], group: str = None
|
||||
) -> Dict[str, str]:
|
||||
"""Update schema for specified level and clean corresponding config."""
|
||||
try:
|
||||
# Determinar rutas de schema y config
|
||||
if level == "1":
|
||||
schema_path = os.path.join(self.data_path, "esquema.json")
|
||||
config_path = os.path.join(self.data_path, "data.json")
|
||||
elif level == "2":
|
||||
schema_path = os.path.join(
|
||||
self.script_groups_path, group, "esquema.json"
|
||||
)
|
||||
config_path = os.path.join(self.script_groups_path, group, "data.json")
|
||||
elif level == "3":
|
||||
if not group:
|
||||
return {
|
||||
"status": "error",
|
||||
"message": "Group is required for level 3",
|
||||
}
|
||||
schema_path = os.path.join(
|
||||
self.script_groups_path, group, "esquema.json"
|
||||
)
|
||||
config_path = (
|
||||
os.path.join(self.working_directory, "data.json")
|
||||
if self.working_directory
|
||||
else None
|
||||
)
|
||||
else:
|
||||
return {"status": "error", "message": "Invalid level"}
|
||||
|
||||
# Ensure directory exists
|
||||
os.makedirs(os.path.dirname(schema_path), exist_ok=True)
|
||||
|
||||
# Validate schema structure
|
||||
if (
|
||||
not isinstance(data, dict)
|
||||
or "type" not in data
|
||||
or "properties" not in data
|
||||
):
|
||||
data = {
|
||||
"type": "object",
|
||||
"properties": data if isinstance(data, dict) else {},
|
||||
}
|
||||
|
||||
# Write schema
|
||||
with open(schema_path, "w", encoding="utf-8") as f:
|
||||
json.dump(data, f, indent=2, ensure_ascii=False)
|
||||
|
||||
# Clean corresponding config file
|
||||
self._clean_config_for_schema(config_path, data)
|
||||
|
||||
return {"status": "success"}
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error updating schema: {str(e)}")
|
||||
return {"status": "error", "message": str(e)}
|
||||
|
||||
def _clean_config_for_schema(
|
||||
self, config_path: str, schema: Dict[str, Any]
|
||||
) -> None:
|
||||
"""Clean configuration file to match schema structure."""
|
||||
if not config_path or not os.path.exists(config_path):
|
||||
return
|
||||
|
||||
try:
|
||||
# Cargar configuración actual
|
||||
with open(config_path, "r", encoding="utf-8") as f:
|
||||
config = json.load(f)
|
||||
|
||||
# Limpiar configuración recursivamente
|
||||
cleaned_config = self._clean_object_against_schema(config, schema)
|
||||
|
||||
# Guardar configuración limpia
|
||||
with open(config_path, "w", encoding="utf-8") as f:
|
||||
json.dump(cleaned_config, f, indent=2, ensure_ascii=False)
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error cleaning config: {str(e)}")
|
||||
|
||||
def _clean_object_against_schema(
|
||||
self, data: Dict[str, Any], schema: Dict[str, Any]
|
||||
) -> Dict[str, Any]:
|
||||
"""Recursively clean object to match schema structure."""
|
||||
if not isinstance(data, dict) or not isinstance(schema, dict):
|
||||
return {}
|
||||
|
||||
result = {}
|
||||
schema_props = schema.get("properties", {})
|
||||
|
||||
for key, value in data.items():
|
||||
# Solo mantener campos que existen en el schema
|
||||
if key in schema_props:
|
||||
prop_schema = schema_props[key]
|
||||
|
||||
# Si es un objeto anidado, limpiar recursivamente
|
||||
if prop_schema.get("type") == "object":
|
||||
result[key] = self._clean_object_against_schema(value, prop_schema)
|
||||
# Si es un enum, verificar que el valor sea válido
|
||||
elif "enum" in prop_schema:
|
||||
if value in prop_schema["enum"]:
|
||||
result[key] = value
|
||||
# Para otros tipos, mantener el valor
|
||||
else:
|
||||
result[key] = value
|
||||
|
||||
return result
|
||||
|
||||
def update_config(
|
||||
self, level: str, data: Dict[str, Any], group: str = None
|
||||
|
@ -132,20 +287,6 @@ class ConfigurationManager:
|
|||
with open(path, "w") as f:
|
||||
json.dump(data, f, indent=2)
|
||||
|
||||
def update_schema(
|
||||
self, level: str, data: Dict[str, Any], group: str = None
|
||||
) -> None:
|
||||
"""Update schema for specified level."""
|
||||
if level == "1":
|
||||
path = os.path.join(self.data_path, "esquema.json")
|
||||
elif level == "2":
|
||||
path = os.path.join(self.script_groups_path, "esquema.json")
|
||||
elif level == "3":
|
||||
path = os.path.join(self.script_groups_path, group, "esquema.json")
|
||||
|
||||
with open(path, "w") as f:
|
||||
json.dump(data, f, indent=2)
|
||||
|
||||
def list_scripts(self, group: str) -> List[Dict[str, str]]:
|
||||
"""List all scripts in a group with their descriptions."""
|
||||
try:
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
{
|
||||
"api_key": "your-api-key-here",
|
||||
"model": "gpt-3.5-turbo",
|
||||
"max_tokens": 1000,
|
||||
"temperature": 0.7
|
||||
}
|
||||
"model": "gpt-3.5-turbo"
|
||||
}
|
|
@ -1,32 +1,20 @@
|
|||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"api_key": {
|
||||
"description": "Tu clave de API para servicios externos",
|
||||
"type": "string",
|
||||
"title": "API Key",
|
||||
"type": "string"
|
||||
},
|
||||
"max_tokens": {
|
||||
"description": "N\u00c3\u00bamero m\u00c3\u00a1ximo de tokens por respuesta",
|
||||
"title": "Tokens M\u00c3\u00a1ximos",
|
||||
"type": "number"
|
||||
"description": "Tu clave de API para servicios externos"
|
||||
},
|
||||
"model": {
|
||||
"type": "string",
|
||||
"title": "Modelo LLM",
|
||||
"description": "Modelo de lenguaje a utilizar",
|
||||
"enum": [
|
||||
"gpt-3.5-turbo",
|
||||
"gpt-4",
|
||||
"claude-v1"
|
||||
],
|
||||
"title": "Modelo LLM",
|
||||
"type": "string"
|
||||
},
|
||||
"temperature": {
|
||||
"description": "Creatividad de las respuestas (0-1)",
|
||||
"maximum": 1,
|
||||
"minimum": 0,
|
||||
"title": "Temperatura",
|
||||
"type": "number"
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
}
|
|
@ -5,9 +5,7 @@ Iniciando ejecución de x1.py...
|
|||
Configuraciones cargadas:
|
||||
Nivel 1: {
|
||||
"api_key": "your-api-key-here",
|
||||
"model": "gpt-3.5-turbo",
|
||||
"max_tokens": 1000,
|
||||
"temperature": 0.7
|
||||
"model": "gpt-3.5-turbo"
|
||||
}
|
||||
Nivel 2: {
|
||||
"input_dir": "D:/Datos/Entrada",
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"type": "object",
|
||||
"properties": {}
|
||||
}
|
|
@ -92,7 +92,7 @@
|
|||
|
||||
// Form rendering functionality
|
||||
async function renderForm(containerId, data) {
|
||||
console.log(`Rendering form for ${containerId}`); // Debug line
|
||||
console.log(`Rendering form for ${containerId} with data:`, data); // Debug line
|
||||
const container = document.getElementById(containerId);
|
||||
const level = containerId.replace('level', '').split('-')[0];
|
||||
|
||||
|
@ -101,13 +101,14 @@
|
|||
const schema = await schemaResponse.json();
|
||||
console.log(`Schema for level ${level}:`, schema); // Debug line
|
||||
|
||||
if (Object.keys(schema).length === 0) {
|
||||
if (!schema || !schema.properties || Object.keys(schema.properties).length === 0) {
|
||||
container.innerHTML = '<p class="text-gray-500">No hay esquema definido para este nivel.</p>';
|
||||
} else {
|
||||
const formHtml = generateFormFields(schema, data, '', level);
|
||||
console.log(`Generated HTML for ${containerId}:`, formHtml.substring(0, 100) + '...'); // Debug line
|
||||
container.innerHTML = formHtml;
|
||||
return;
|
||||
}
|
||||
|
||||
const formHtml = generateFormFields(schema, data || {}, '', level);
|
||||
console.log(`Generated HTML for ${containerId}:`, formHtml.substring(0, 100) + '...'); // Debug line
|
||||
container.innerHTML = formHtml;
|
||||
} catch (error) {
|
||||
console.error(`Error rendering form ${containerId}:`, error);
|
||||
container.innerHTML = '<p class="text-red-500">Error cargando el esquema.</p>';
|
||||
|
@ -115,10 +116,18 @@
|
|||
}
|
||||
|
||||
function generateFormFields(schema, data, prefix, level) {
|
||||
console.log('Generating fields with data:', { schema, data, prefix, level }); // Debug line
|
||||
let html = '';
|
||||
|
||||
if (!schema.properties) {
|
||||
console.warn('Schema has no properties');
|
||||
return html;
|
||||
}
|
||||
|
||||
for (const [key, def] of Object.entries(schema.properties)) {
|
||||
const fullKey = prefix ? `${prefix}.${key}` : key;
|
||||
const value = getValue(data, fullKey);
|
||||
console.log(`Field ${fullKey}:`, { definition: def, value: value }); // Debug line
|
||||
|
||||
html += `<div class="mb-4">
|
||||
<label class="block text-gray-700 text-sm font-bold mb-2">${def.title || key}</label>`;
|
||||
|
@ -139,6 +148,15 @@
|
|||
return html;
|
||||
}
|
||||
|
||||
function getValue(data, path) {
|
||||
console.log('Getting value for path:', { path, data }); // Debug line
|
||||
if (!data || !path) return undefined;
|
||||
|
||||
const value = path.split('.').reduce((obj, key) => obj?.[key], data);
|
||||
console.log('Found value:', value); // Debug line
|
||||
return value;
|
||||
}
|
||||
|
||||
function generateInputField(def, key, value, level) {
|
||||
const baseClasses = "w-full p-2 border rounded bg-green-50"; // Agregado bg-green-50 para fondo verde claro
|
||||
|
||||
|
@ -177,33 +195,45 @@
|
|||
try {
|
||||
console.log('Loading schema for level:', level); // Debug line
|
||||
const response = await fetch(`/api/schema/${level}?group=${currentGroup}`);
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
const schema = await response.json();
|
||||
console.log('Loaded schema:', schema); // Debug line
|
||||
|
||||
// Show schema editor modal
|
||||
const modal = document.getElementById('schema-editor');
|
||||
if (!modal) {
|
||||
throw new Error('Schema editor modal not found');
|
||||
}
|
||||
modal.classList.remove('hidden');
|
||||
|
||||
// Inicializar JSON editor
|
||||
const jsonEditor = document.getElementById('json-editor');
|
||||
jsonEditor.value = JSON.stringify(schema, null, 2);
|
||||
// Inicializar el esquema si está vacío
|
||||
const finalSchema = Object.keys(schema).length === 0 ?
|
||||
{ type: 'object', properties: {} } : schema;
|
||||
|
||||
// Inicializar visual editor
|
||||
// Inicializar editores
|
||||
const jsonEditor = document.getElementById('json-editor');
|
||||
const visualEditor = document.getElementById('visual-editor');
|
||||
const schemaLevel = document.getElementById('schema-level');
|
||||
|
||||
if (!jsonEditor || !visualEditor || !schemaLevel) {
|
||||
throw new Error('Required editor elements not found');
|
||||
}
|
||||
|
||||
jsonEditor.value = JSON.stringify(finalSchema, null, 2);
|
||||
visualEditor.innerHTML = '<div id="schema-fields" class="mb-4"></div>' +
|
||||
'<button onclick="addSchemaField()" class="mt-4 bg-green-500 text-white px-4 py-2 rounded">Agregar Campo</button>';
|
||||
schemaLevel.value = level;
|
||||
|
||||
// Renderizar campos existentes
|
||||
renderVisualEditor(schema);
|
||||
|
||||
// Guardar nivel actual
|
||||
document.getElementById('schema-level').value = level;
|
||||
// Renderizar editor visual
|
||||
renderVisualEditor(finalSchema);
|
||||
|
||||
// Activar pestaña visual por defecto
|
||||
switchEditorMode('visual');
|
||||
} catch (error) {
|
||||
console.error('Error loading schema:', error);
|
||||
alert('Error cargando el esquema');
|
||||
alert('Error cargando el esquema: ' + error.message);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -218,11 +248,27 @@
|
|||
jsonEditor.classList.add('hidden');
|
||||
visualTab.classList.add('border-blue-500');
|
||||
jsonTab.classList.remove('border-blue-500');
|
||||
|
||||
// Actualizar el editor visual desde JSON
|
||||
try {
|
||||
const schema = JSON.parse(jsonEditor.value);
|
||||
renderVisualEditor(schema);
|
||||
} catch (e) {
|
||||
console.error('Error parsing JSON:', e);
|
||||
}
|
||||
} else {
|
||||
visualEditor.classList.add('hidden');
|
||||
jsonEditor.classList.remove('hidden');
|
||||
visualTab.classList.remove('border-blue-500');
|
||||
jsonTab.classList.add('border-blue-500');
|
||||
|
||||
// Actualizar el JSON desde el editor visual
|
||||
try {
|
||||
const schema = updateVisualSchema();
|
||||
jsonEditor.value = JSON.stringify(schema, null, 2);
|
||||
} catch (e) {
|
||||
console.error('Error updating JSON:', e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -333,91 +379,85 @@
|
|||
|
||||
// Funciones de actualización del esquema visual
|
||||
function updateVisualSchema() {
|
||||
const fields = document.getElementById('schema-fields').children;
|
||||
const schema = {
|
||||
type: 'object',
|
||||
properties: {}
|
||||
};
|
||||
|
||||
Array.from(fields).forEach(field => {
|
||||
const inputs = field.getElementsByTagName('input');
|
||||
const select = field.getElementsByTagName('select')[0];
|
||||
const key = inputs[0].value;
|
||||
|
||||
schema.properties[key] = {
|
||||
type: select.value === 'enum' ? 'string' : select.value,
|
||||
title: inputs[1].value,
|
||||
description: inputs[2].value
|
||||
try {
|
||||
const fields = document.getElementById('schema-fields').children;
|
||||
const schema = {
|
||||
type: 'object',
|
||||
properties: {}
|
||||
};
|
||||
|
||||
if (select.value === 'enum') {
|
||||
const textarea = field.getElementsByTagName('textarea')[0];
|
||||
schema.properties[key].enum = textarea.value.split('\n').filter(v => v.trim());
|
||||
}
|
||||
});
|
||||
Array.from(fields).forEach(field => {
|
||||
const inputs = field.getElementsByTagName('input');
|
||||
const select = field.getElementsByTagName('select')[0];
|
||||
const key = inputs[0].value;
|
||||
|
||||
schema.properties[key] = {
|
||||
type: select.value === 'enum' ? 'string' : select.value,
|
||||
title: inputs[1].value,
|
||||
description: inputs[2].value
|
||||
};
|
||||
|
||||
document.getElementById('schema-content').value = JSON.stringify(schema, null, 2);
|
||||
return schema;
|
||||
if (select.value === 'enum') {
|
||||
const textarea = field.getElementsByTagName('textarea')[0];
|
||||
if (textarea) {
|
||||
schema.properties[key].enum = textarea.value.split('\n').filter(v => v.trim());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Actualizar el JSON editor directamente
|
||||
const jsonEditor = document.getElementById('json-editor');
|
||||
if (jsonEditor) {
|
||||
jsonEditor.value = JSON.stringify(schema, null, 2);
|
||||
}
|
||||
|
||||
return schema;
|
||||
} catch (error) {
|
||||
console.error('Error updating schema:', error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async function saveSchema() {
|
||||
try {
|
||||
const level = document.getElementById('schema-level').value;
|
||||
const schema = updateVisualSchema();
|
||||
let schema;
|
||||
|
||||
await fetch(`/api/schema/${level}?group=${currentGroup}`, {
|
||||
// Obtener el esquema según el modo activo
|
||||
const visualEditor = document.getElementById('visual-editor');
|
||||
const jsonEditor = document.getElementById('json-editor');
|
||||
|
||||
if (!visualEditor.classList.contains('hidden')) {
|
||||
schema = updateVisualSchema();
|
||||
} else {
|
||||
schema = JSON.parse(jsonEditor.value);
|
||||
}
|
||||
|
||||
console.log('Saving schema:', schema); // Debug line
|
||||
|
||||
const response = await fetch(`/api/schema/${level}?group=${currentGroup}`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(schema)
|
||||
});
|
||||
|
||||
const response = await fetch(`/api/config/${level}?group=${currentGroup}`);
|
||||
const data = await response.json();
|
||||
renderForm(`level${level}-form`, data);
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
// Recargar el formulario
|
||||
const configResponse = await fetch(`/api/config/${level}?group=${currentGroup}`);
|
||||
const data = await configResponse.json();
|
||||
await renderForm(`level${level}-form`, data);
|
||||
|
||||
// Cerrar modal
|
||||
document.getElementById('schema-editor').classList.add('hidden');
|
||||
} catch (e) {
|
||||
console.error('Error saving schema:', e);
|
||||
alert('Error guardando esquema: ' + e.message);
|
||||
}
|
||||
}
|
||||
|
||||
function getValue(data, path) {
|
||||
return path.split('.').reduce((obj, key) => obj?.[key], data);
|
||||
}
|
||||
|
||||
// Actualizar configuración cuando cambia un campo
|
||||
async function updateConfig(level, key, value) {
|
||||
const group = currentGroup;
|
||||
// Obtener configuración actual
|
||||
const response = await fetch(`/api/config/${level}?group=${group}`);
|
||||
const config = await response.json();
|
||||
|
||||
// Actualizar el valor usando la ruta del campo
|
||||
setNestedValue(config, key, value);
|
||||
|
||||
// Guardar configuración actualizada
|
||||
await fetch(`/api/config/${level}?group=${group}`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(config)
|
||||
});
|
||||
}
|
||||
|
||||
// Función auxiliar para establecer valor en objeto anidado
|
||||
function setNestedValue(obj, path, value) {
|
||||
const keys = path.split('.');
|
||||
let current = obj;
|
||||
|
||||
for (let i = 0; i < keys.length - 1; i++) {
|
||||
if (!(keys[i] in current)) {
|
||||
current[keys[i]] = {};
|
||||
}
|
||||
current = current[keys[i]];
|
||||
}
|
||||
|
||||
current[keys[keys.length - 1]] = value;
|
||||
}
|
||||
|
||||
async function setWorkingDirectory() {
|
||||
if (!currentGroup) {
|
||||
alert('Por favor, seleccione un grupo de scripts primero');
|
||||
|
@ -537,6 +577,17 @@
|
|||
}
|
||||
currentGroup = selectElement.value; // Siempre establecer currentGroup con el valor actual del select
|
||||
console.log('Current group initialized as:', currentGroup); // Debug line
|
||||
updateGroupDescription(); // Actualizar descripción inicial
|
||||
|
||||
// Configurar el evento de cambio de grupo
|
||||
selectElement.addEventListener('change', async (e) => {
|
||||
currentGroup = e.target.value;
|
||||
localStorage.setItem('selectedGroup', e.target.value);
|
||||
console.log('Group changed to:', currentGroup); // Debug line
|
||||
updateGroupDescription(); // Actualizar descripción al cambiar
|
||||
await initWorkingDirectory();
|
||||
await loadConfigs();
|
||||
});
|
||||
|
||||
// Luego cargar el directorio de trabajo
|
||||
await initWorkingDirectory();
|
||||
|
@ -582,6 +633,13 @@
|
|||
logArea.innerHTML += lines;
|
||||
logArea.scrollTop = logArea.scrollHeight;
|
||||
}
|
||||
|
||||
function updateGroupDescription() {
|
||||
const select = document.getElementById('script-group');
|
||||
const option = select.options[select.selectedIndex];
|
||||
const description = option.getAttribute('data-description');
|
||||
document.getElementById('group-description').textContent = description;
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body class="bg-gray-100">
|
||||
|
@ -606,11 +664,16 @@
|
|||
<!-- Script Group Selection -->
|
||||
<div class="mb-8 bg-white p-6 rounded-lg shadow">
|
||||
<h2 class="text-xl font-bold mb-4">Grupo de Scripts</h2>
|
||||
<select id="script-group" class="w-full p-2 border rounded">
|
||||
<select id="script-group" class="w-full p-2 border rounded mb-2">
|
||||
{% for group in script_groups %}
|
||||
<option value="{{ group }}">{{ group }}</option>
|
||||
<option value="{{ group.id }}" data-description="{{ group.description }}">{{ group.name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<p id="group-description" class="text-gray-600 text-sm italic"></p>
|
||||
<div class="text-xs text-gray-500 mt-2">
|
||||
<span id="group-version"></span>
|
||||
<span id="group-author"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Level 2 Configuration -->
|
||||
|
|
Loading…
Reference in New Issue