Se implementó la funcionalidad para abrir archivos seleccionados desde el editor de esquemas, añadiendo un botón "Abrir" que permite al usuario abrir archivos con la aplicación predeterminada del sistema. Se desarrolló una nueva ruta API `/api/open-file` para manejar la apertura de archivos, con soporte multiplataforma para Windows, macOS y Linux. Además, se realizaron mejoras en la interfaz de usuario para habilitar el botón "Abrir" solo cuando se selecciona un archivo. Se actualizó la documentación en `MemoriaDeEvolucion.md` para reflejar estos cambios.

This commit is contained in:
Miguel 2025-07-14 17:33:37 +02:00
parent 4d1de71990
commit 3b3cfd7062
4 changed files with 680 additions and 288 deletions

View File

@ -58,3 +58,13 @@ El sistema está diseñado para trabajar con directorios específicos donde los
- Documentación inicial del sistema ParamManagerScripts
- Descripción de la arquitectura y funcionalidades principales
- Establecimiento de la estructura de memoria de evolución
### [2024-12-19] - Implementación de Campos de Tipo Archivo
- **Nueva funcionalidad**: Agregado soporte para campos de tipo "Archivo" en el editor de esquemas
- **Selección de archivos**: Implementado diálogo de selección de archivos con `tkinter.filedialog.askopenfilename`
- **Botón "Abrir"**: Agregado botón adicional para abrir archivos seleccionados con la aplicación predeterminada del sistema
- **Compatibilidad multiplataforma**: Soporte para Windows (`os.startfile`), macOS (`open`) y Linux (`xdg-open`)
- **Validaciones**: Verificación de existencia y tipo de archivo antes de intentar abrirlo
- **Integración UI**: Botón "Abrir" se habilita automáticamente cuando se selecciona un archivo
- **Endpoints API**: Nuevas rutas `/api/browse-files` y `/api/open-file` para manejo de archivos
- **Casos de uso**: Ideal para archivos Excel, Markdown, documentos y cualquier tipo de archivo que requiera apertura rápida

878
app.py

File diff suppressed because it is too large Load Diff

View File

@ -1,19 +1,19 @@
[16:52:51] Iniciando ejecución de x3_excel_to_md.py en C:\Trabajo\SIDEL\13 - E5.007560 - Modifica O&U - SAE235\Reporte\Analisis\Siemens...
[16:52:52] === Conversión de archivos Excel a Markdown ===
[16:52:52] 1. Convirtiendo Excel de tags de TIA Portal...
[16:52:52] Usando directorio de trabajo: C:\Trabajo\SIDEL\13 - E5.007560 - Modifica O&U - SAE235\Reporte\Analisis\Siemens
[16:52:52] Configuración de paths cargada desde: C:\Trabajo\SIDEL\13 - E5.007560 - Modifica O&U - SAE235\Reporte\Analisis\Siemens\io_paths_config.json
[16:52:52] Buscando archivos Excel en: C:\Trabajo\SIDEL\13 - E5.007560 - Modifica O&U - SAE235\Reporte\IOTags
[16:52:52] Archivo Excel encontrado automáticamente: C:\Trabajo\SIDEL\13 - E5.007560 - Modifica O&U - SAE235\Reporte\IOTags\All_PLCTags.xlsx
[16:52:52] Procesando archivo Excel: C:\Trabajo\SIDEL\13 - E5.007560 - Modifica O&U - SAE235\Reporte\IOTags\All_PLCTags.xlsx...
[16:52:52] Paths configurados para procesar: ['Inputs', 'Outputs', 'OutputsFesto', 'IO Not in Hardware\\InputsMaster', 'IO Not in Hardware\\OutputsMaster']
[16:52:53] ¡Éxito! Archivo Markdown generado en: C:\Trabajo\SIDEL\13 - E5.007560 - Modifica O&U - SAE235\Reporte\Analisis\Siemens\Resultados\Master IO Tags.md
[16:52:53] ==================================================
[16:52:53] 2. Convirtiendo Excel de IO desde esquema eléctrico...
[16:52:53] Usando directorio de trabajo: C:\Trabajo\SIDEL\13 - E5.007560 - Modifica O&U - SAE235\Reporte\Analisis\Siemens
[16:52:53] Procesando archivo Excel de IO: C:/Trabajo/SIDEL/13 - E5.007560 - Modifica O&U - SAE235/Reporte/IO.xlsx...
[16:52:53] Columnas encontradas en el Excel: ['Unnamed: 0', 'Unnamed: 1', 'Unnamed: 2', 'Unnamed: 3', 'Unnamed: 4', 'Unnamed: 5']
[16:52:53] ¡Éxito! Archivo Markdown de IO generado en: C:\Trabajo\SIDEL\13 - E5.007560 - Modifica O&U - SAE235\Reporte\Analisis\Siemens\Resultados\Hardware_ED.md
[16:52:53] === Proceso completado ===
[16:52:53] Ejecución de x3_excel_to_md.py finalizada (success). Duración: 0:00:01.794236.
[16:52:53] Log completo guardado en: D:\Proyectos\Scripts\ParamManagerScripts\backend\script_groups\IO_adaptation\.log\log_x3_excel_to_md.txt
[17:10:45] Iniciando ejecución de x3_excel_to_md.py en C:\Trabajo\SIDEL\13 - E5.007560 - Modifica O&U - SAE235\Reporte\Analisis\Siemens...
[17:10:46] === Conversión de archivos Excel a Markdown ===
[17:10:46] 1. Convirtiendo Excel de tags de TIA Portal...
[17:10:46] Usando directorio de trabajo: C:\Trabajo\SIDEL\13 - E5.007560 - Modifica O&U - SAE235\Reporte\Analisis\Siemens
[17:10:46] Configuración de paths cargada desde: C:\Trabajo\SIDEL\13 - E5.007560 - Modifica O&U - SAE235\Reporte\Analisis\Siemens\io_paths_config.json
[17:10:46] Buscando archivos Excel en: C:\Trabajo\SIDEL\13 - E5.007560 - Modifica O&U - SAE235\Reporte\IOTags
[17:10:46] Archivo Excel encontrado automáticamente: C:\Trabajo\SIDEL\13 - E5.007560 - Modifica O&U - SAE235\Reporte\IOTags\All_PLCTags.xlsx
[17:10:46] Procesando archivo Excel: C:\Trabajo\SIDEL\13 - E5.007560 - Modifica O&U - SAE235\Reporte\IOTags\All_PLCTags.xlsx...
[17:10:46] Paths configurados para procesar: ['Inputs', 'Outputs', 'OutputsFesto', 'IO Not in Hardware\\InputsMaster', 'IO Not in Hardware\\OutputsMaster']
[17:10:47] ¡Éxito! Archivo Markdown generado en: C:\Trabajo\SIDEL\13 - E5.007560 - Modifica O&U - SAE235\Reporte\Analisis\Siemens\Resultados\Master IO Tags.md
[17:10:47] ==================================================
[17:10:47] 2. Convirtiendo Excel de IO desde esquema eléctrico...
[17:10:47] Usando directorio de trabajo: C:\Trabajo\SIDEL\13 - E5.007560 - Modifica O&U - SAE235\Reporte\Analisis\Siemens
[17:10:47] Procesando archivo Excel de IO: C:/Trabajo/SIDEL/13 - E5.007560 - Modifica O&U - SAE235/Reporte/IO.xlsx...
[17:10:47] Columnas encontradas en el Excel: ['Master TAG', 'IO', 'Sensor', 'Descripcion', 'Descripcion.1']
[17:10:47] ¡Éxito! Archivo Markdown de IO generado en: C:\Trabajo\SIDEL\13 - E5.007560 - Modifica O&U - SAE235\Reporte\Analisis\Siemens\Resultados\Hardware_ED.md
[17:10:47] === Proceso completado ===
[17:10:47] Ejecución de x3_excel_to_md.py finalizada (success). Duración: 0:00:01.379917.
[17:10:47] Log completo guardado en: D:\Proyectos\Scripts\ParamManagerScripts\backend\script_groups\IO_adaptation\.log\log_x3_excel_to_md.txt

View File

@ -406,6 +406,13 @@ function generateInputField(def, key, value, level) {
data-key="${key}">
Buscar...
</button>
<button type="button"
onclick="openFieldFile(this)"
class="bg-green-500 text-white px-3 py-1 rounded hover:bg-green-600"
data-key="${key}"
${!value ? 'disabled' : ''}>
Abrir
</button>
</div>`;
}
if (def.enum) {
@ -467,6 +474,12 @@ async function browseFieldFile(button) {
bubbles: true
});
input.dispatchEvent(event);
// Habilitar el botón "Abrir" después de seleccionar un archivo
const openButton = button.parentElement.querySelector('button[onclick="openFieldFile(this)"]');
if (openButton) {
openButton.disabled = false;
}
}
} catch (error) {
console.error('Error browsing file:', error);
@ -474,6 +487,35 @@ async function browseFieldFile(button) {
}
}
// Agregar función para abrir el archivo seleccionado
async function openFieldFile(button) {
const input = button.parentElement.querySelector('input');
const filePath = input.value;
if (!filePath || filePath.trim() === '') {
alert('No hay archivo seleccionado para abrir');
return;
}
try {
const response = await fetch('/api/open-file', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ path: filePath })
});
const result = await response.json();
if (result.status === 'success') {
console.log('Archivo abierto correctamente');
} else {
alert(`Error al abrir el archivo: ${result.message}`);
}
} catch (error) {
console.error('Error opening file:', error);
alert('Error al abrir el archivo');
}
}
async function modifySchema(level) {
try {
console.log('Loading schema for level:', level); // Debug line