// frontend/static/js/scripts.js
async function loadScriptGroups() {
try {
const groups = await apiRequest('/script-groups');
const select = document.getElementById('groupSelect');
const lastGroupId = localStorage.getItem('lastGroupId');
// Remover event listener anterior si existe
const oldHandler = select.onchange;
if (oldHandler) {
select.removeEventListener('change', oldHandler);
}
// Actualizar opciones
select.innerHTML = `
${groups.map(group => `
`).join('')}
`;
// Agregar nuevo event listener
select.addEventListener('change', handleGroupChange);
// Si hay un grupo guardado, cargarlo
if (lastGroupId && groups.some(g => g.id === lastGroupId)) {
await selectGroup(lastGroupId);
}
} catch (error) {
console.error('Error loading script groups:', error);
showError('Error loading script groups');
}
}
async function handleGroupChange(event) {
const groupId = event.target.value;
if (groupId) {
localStorage.setItem('lastGroupId', groupId);
await selectGroup(groupId);
} else {
localStorage.removeItem('lastGroupId');
updateGroupDisplay(null);
}
}
async function selectGroup(groupId) {
try {
// Cargar configuración del grupo
const config = await apiRequest(`/script-groups/${groupId}/config`);
currentGroup = { id: groupId, ...config };
// Actualizar displays
updateGroupDisplay(currentGroup);
// Cargar scripts si hay un directorio de trabajo configurado
if (currentGroup.work_dir) {
await loadGroupScripts(groupId);
// Cargar configuración del directorio de trabajo
const workDirConfig = await apiRequest(`/workdir-config/${groupId}`);
updateWorkDirConfig(workDirConfig);
} else {
document.getElementById('scriptList').innerHTML = `
Please configure a work directory for this group first
`;
}
} catch (error) {
console.error('Error selecting group:', error);
showError('Error loading group configuration');
}
}
async function loadGroupScripts(groupId) {
if (!currentGroup?.work_dir) {
return;
}
try {
// Cargar scripts y esquema
const [scripts, schema] = await Promise.all([
apiRequest(`/script-groups/${groupId}/scripts`),
apiRequest(`/script-groups/${groupId}/schema`)
]);
const scriptList = document.getElementById('scriptList');
scriptList.innerHTML = `
${scripts.map(script => `
${script.name}
${script.description || 'No description available'}
`).join('')}
`;
} catch (error) {
console.error('Error loading group scripts:', error);
showError('Error loading scripts');
}
}
async function runScript(scriptId) {
if (!currentGroup?.work_dir) {
showError('No work directory configured');
return;
}
try {
const result = await apiRequest(`/script-groups/${currentGroup.id}/scripts/${scriptId}/run`, {
method: 'POST',
body: JSON.stringify({
work_dir: currentGroup.work_dir,
profile: currentProfile
})
});
if (result.error) {
showError(result.error);
} else {
showSuccess('Script executed successfully');
if (result.output) {
const outputArea = document.getElementById('outputArea');
const timestamp = new Date().toLocaleTimeString();
outputArea.innerHTML += `\n[${timestamp}] ${result.output}`;
outputArea.scrollTop = outputArea.scrollHeight;
}
}
} catch (error) {
showError('Error executing script');
}
}
async function editGroupConfig() {
if (!currentGroup) return;
try {
const schema = await apiRequest(`/script-groups/${currentGroup.id}/schema`);
const content = `
`;
const modal = createModal('Edit Group Configuration', content, true);
modal.querySelector('[onclick="saveModal(this)"]').onclick = () => saveGroupConfig(modal);
} catch (error) {
showError('Error loading group configuration');
}
}
async function saveGroupConfig(modal) {
if (!currentGroup) return;
const form = modal.querySelector('#groupConfigForm');
const formData = new FormData(form);
const config = {};
formData.forEach((value, key) => {
if (value === 'true') value = true;
else if (value === 'false') value = false;
else if (!isNaN(value) && value !== '') value = Number(value);
config[key] = value;
});
try {
await apiRequest(`/script-groups/${currentGroup.id}/config`, {
method: 'PUT',
body: JSON.stringify(config)
});
closeModal(modal);
showSuccess('Group configuration updated');
await selectGroup(currentGroup.id);
} catch (error) {
showError('Error saving group configuration');
}
}
async function editGroupSchema() {
if (!currentGroup) return;
try {
const schema = await apiRequest(`/script-groups/${currentGroup.id}/schema`);
const content = `
`;
const modal = createModal('Edit Group Schema', content, true);
modal.querySelector('[onclick="saveModal(this)"]').onclick = () => saveGroupSchema(modal);
} catch (error) {
showError('Error loading group schema');
}
}
async function saveGroupSchema(modal) {
const schema = {
group_name: modal.querySelector('[name="group_name"]').value,
description: modal.querySelector('[name="description"]').value,
config_schema: {}
};
// Recopilar definiciones de campos
modal.querySelectorAll('.schema-field').forEach(field => {
const key = field.querySelector('[name="field_name"]').value;
const type = field.querySelector('[name="field_type"]').value;
if (!key) return; // Ignorar campos sin nombre
const fieldSchema = {
type,
description: field.querySelector('[name="field_description"]').value,
required: field.querySelector('[name="field_required"]').value === 'true'
};
// Procesar valor por defecto según el tipo
const defaultValue = field.querySelector('[name="field_default"]').value;
if (defaultValue) {
if (type === 'number') {
fieldSchema.default = Number(defaultValue);
} else if (type === 'boolean') {
fieldSchema.default = defaultValue === 'true';
} else {
fieldSchema.default = defaultValue;
}
}
// Procesar opciones para campos tipo select
if (type === 'select') {
const optionsStr = field.querySelector('[name="field_options"]').value;
fieldSchema.options = optionsStr.split(',').map(opt => opt.trim()).filter(Boolean);
}
schema.config_schema[key] = fieldSchema;
});
try {
await apiRequest(`/script-groups/${currentGroup.id}/schema`, {
method: 'PUT',
body: JSON.stringify(schema)
});
closeModal(modal);
showSuccess('Group schema updated');
// Recargar configuración del grupo
await editGroupConfig();
} catch (error) {
showError('Error saving group schema');
}
}
function updateScriptList(scripts) {
const scriptList = document.getElementById('scriptList');
if (!scriptList) return;
if (!scripts || !scripts.length) {
scriptList.innerHTML = `
No scripts available
`;
return;
}
scriptList.innerHTML = `
${scripts.map(script => `
${script.name}
${script.description || 'No description available'}
`).join('')}
`;
}
async function restoreScriptGroup() {
const lastGroupId = localStorage.getItem('lastGroupId');
if (lastGroupId) {
const select = document.getElementById('groupSelect');
if (select) {
select.value = lastGroupId;
if (select.value === lastGroupId) { // Verifica que el grupo aún existe
await selectGroup(lastGroupId);
} else {
localStorage.removeItem('lastGroupId');
}
}
}
}
function updateGroupDisplay(group) {
const configContainer = document.getElementById('groupConfig');
if (!configContainer) return;
if (!group) {
configContainer.innerHTML = '';
return;
}
configContainer.innerHTML = `
${group.name || 'Unnamed Group'}
${group.description || 'No description'}
${group.work_dir || 'Not configured'}
`;
}
async function selectGroupWorkDir() {
if (!currentGroup) {
showError('No group selected');
return;
}
try {
const response = await apiRequest('/select-directory');
if (response.path) {
const updatedConfig = {
...currentGroup,
work_dir: response.path
};
await apiRequest(`/script-groups/${currentGroup.id}/config`, {
method: 'PUT',
body: JSON.stringify(updatedConfig)
});
currentGroup = updatedConfig;
updateGroupDisplay(currentGroup);
showSuccess('Work directory updated successfully');
// Recargar scripts si hay
await loadGroupScripts(currentGroup.id);
}
} catch (error) {
showError('Failed to update work directory');
}
}
// Inicializar cuando la página carga
document.addEventListener('DOMContentLoaded', async () => {
await loadScriptGroups();
await restoreScriptGroup();
});