228 lines
8.1 KiB
Python
228 lines
8.1 KiB
Python
"""Pestaña de Post-Procesamiento con agente inteligente."""
|
|
import customtkinter as ctk
|
|
from gui.styles import AppStyles
|
|
|
|
|
|
class PostProcessTab:
|
|
"""UI de la pestaña de Post-Procesamiento de CSV."""
|
|
|
|
def __init__(self, parent_tab):
|
|
self.tab = parent_tab
|
|
self.fonts = AppStyles.get_fonts()
|
|
self.colors = AppStyles.get_colors()
|
|
self.spacing = AppStyles.get_spacing()
|
|
|
|
self._setup_layout()
|
|
self._create_file_section()
|
|
self._create_preview_section()
|
|
self._create_instructions_section()
|
|
self._create_code_section()
|
|
self._create_log_section()
|
|
self._create_result_section()
|
|
|
|
# -- Layout ------------------------------------------------------------------
|
|
|
|
def _setup_layout(self):
|
|
self.tab.grid_columnconfigure(0, weight=1)
|
|
self.tab.grid_rowconfigure(0, weight=1)
|
|
|
|
self.scroll = ctk.CTkScrollableFrame(self.tab, fg_color="transparent")
|
|
self.scroll.grid(row=0, column=0, sticky="nsew", padx=10, pady=10)
|
|
self.scroll.grid_columnconfigure(0, weight=1)
|
|
|
|
# -- Sección archivo ---------------------------------------------------------
|
|
|
|
def _create_file_section(self):
|
|
frame = ctk.CTkFrame(self.scroll)
|
|
frame.grid(row=0, column=0, sticky="ew", padx=5, pady=(5, 2))
|
|
frame.grid_columnconfigure(1, weight=1)
|
|
|
|
lbl_title = ctk.CTkLabel(frame, text="Archivo CSV", font=self.fonts["section"])
|
|
lbl_title.grid(row=0, column=0, columnspan=3, sticky="w", padx=15, pady=(10, 5))
|
|
|
|
self.btn_select_csv = ctk.CTkButton(
|
|
frame, text="Seleccionar CSV", font=self.fonts["ui"], width=160,
|
|
)
|
|
self.btn_select_csv.grid(row=1, column=0, padx=15, pady=8, sticky="w")
|
|
|
|
self.lbl_csv_path = ctk.CTkLabel(
|
|
frame, text="Ningún archivo seleccionado",
|
|
font=self.fonts["italic_small"], text_color=self.colors["gray_light"],
|
|
)
|
|
self.lbl_csv_path.grid(row=1, column=1, padx=10, pady=8, sticky="w")
|
|
|
|
# -- Preview datos -----------------------------------------------------------
|
|
|
|
def _create_preview_section(self):
|
|
frame = ctk.CTkFrame(self.scroll)
|
|
frame.grid(row=1, column=0, sticky="ew", padx=5, pady=2)
|
|
frame.grid_columnconfigure(0, weight=1)
|
|
|
|
lbl = ctk.CTkLabel(frame, text="Vista previa (muestra)", font=self.fonts["section"])
|
|
lbl.grid(row=0, column=0, sticky="w", padx=15, pady=(10, 5))
|
|
|
|
self.txt_preview = ctk.CTkTextbox(
|
|
frame, height=200, font=self.fonts["mono_small"],
|
|
state="disabled", wrap="none",
|
|
)
|
|
self.txt_preview.grid(row=1, column=0, sticky="ew", padx=15, pady=(0, 10))
|
|
|
|
# -- Instrucciones -----------------------------------------------------------
|
|
|
|
def _create_instructions_section(self):
|
|
frame = ctk.CTkFrame(self.scroll)
|
|
frame.grid(row=2, column=0, sticky="ew", padx=5, pady=2)
|
|
frame.grid_columnconfigure(0, weight=1)
|
|
|
|
lbl = ctk.CTkLabel(
|
|
frame, text="Instrucciones de transformación", font=self.fonts["section"],
|
|
)
|
|
lbl.grid(row=0, column=0, sticky="w", padx=15, pady=(10, 2))
|
|
|
|
hint = ctk.CTkLabel(
|
|
frame,
|
|
text="Describe qué cambios quieres aplicar y en qué columnas. Ejemplo: "
|
|
"\"En la columna 'monto', multiplicar por 1.19 para agregar IVA\"",
|
|
font=self.fonts["italic_small"], text_color=self.colors["gray_light"],
|
|
wraplength=900, justify="left",
|
|
)
|
|
hint.grid(row=1, column=0, sticky="w", padx=15, pady=(0, 5))
|
|
|
|
self.txt_instructions = ctk.CTkTextbox(
|
|
frame, height=90, font=self.fonts["ui"], wrap="word",
|
|
)
|
|
self.txt_instructions.grid(row=2, column=0, sticky="ew", padx=15, pady=(0, 5))
|
|
|
|
btn_frame = ctk.CTkFrame(frame, fg_color="transparent")
|
|
btn_frame.grid(row=3, column=0, sticky="ew", padx=15, pady=(0, 10))
|
|
|
|
self.btn_run = ctk.CTkButton(
|
|
btn_frame, text="Generar y Aplicar", font=self.fonts["button_large"],
|
|
fg_color=self.colors["primary_button"], hover_color=self.colors["primary_hover"],
|
|
height=38,
|
|
)
|
|
self.btn_run.pack(side="left")
|
|
|
|
self.lbl_status = ctk.CTkLabel(
|
|
btn_frame, text="", font=self.fonts["italic_small"],
|
|
text_color=self.colors["gray_light"],
|
|
)
|
|
self.lbl_status.pack(side="left", padx=15)
|
|
|
|
# -- Código generado ---------------------------------------------------------
|
|
|
|
def _create_code_section(self):
|
|
frame = ctk.CTkFrame(self.scroll)
|
|
frame.grid(row=3, column=0, sticky="ew", padx=5, pady=2)
|
|
frame.grid_columnconfigure(0, weight=1)
|
|
|
|
lbl = ctk.CTkLabel(frame, text="Código generado", font=self.fonts["section"])
|
|
lbl.grid(row=0, column=0, sticky="w", padx=15, pady=(10, 5))
|
|
|
|
self.txt_code = ctk.CTkTextbox(
|
|
frame, height=180, font=self.fonts["mono_small"],
|
|
state="disabled", wrap="none",
|
|
)
|
|
self.txt_code.grid(row=1, column=0, sticky="ew", padx=15, pady=(0, 10))
|
|
|
|
# -- Log de ejecución --------------------------------------------------------
|
|
|
|
def _create_log_section(self):
|
|
frame = ctk.CTkFrame(self.scroll)
|
|
frame.grid(row=4, column=0, sticky="ew", padx=5, pady=2)
|
|
frame.grid_columnconfigure(0, weight=1)
|
|
|
|
lbl = ctk.CTkLabel(frame, text="Log de ejecución", font=self.fonts["section"])
|
|
lbl.grid(row=0, column=0, sticky="w", padx=15, pady=(10, 5))
|
|
|
|
self.txt_log = ctk.CTkTextbox(
|
|
frame, height=100, font=self.fonts["mono_small"],
|
|
state="disabled", wrap="word",
|
|
)
|
|
self.txt_log.grid(row=1, column=0, sticky="ew", padx=15, pady=(0, 10))
|
|
|
|
# -- Resultado ---------------------------------------------------------------
|
|
|
|
def _create_result_section(self):
|
|
frame = ctk.CTkFrame(self.scroll)
|
|
frame.grid(row=5, column=0, sticky="ew", padx=5, pady=(2, 5))
|
|
frame.grid_columnconfigure(0, weight=1)
|
|
|
|
top = ctk.CTkFrame(frame, fg_color="transparent")
|
|
top.grid(row=0, column=0, sticky="ew", padx=15, pady=(10, 5))
|
|
top.grid_columnconfigure(0, weight=1)
|
|
|
|
lbl = ctk.CTkLabel(top, text="Vista previa del resultado", font=self.fonts["section"])
|
|
lbl.pack(side="left")
|
|
|
|
self.btn_save = ctk.CTkButton(
|
|
top, text="Guardar CSV", font=self.fonts["ui"], width=140,
|
|
fg_color=self.colors["success"], hover_color=self.colors["success_hover"],
|
|
state="disabled",
|
|
)
|
|
self.btn_save.pack(side="right")
|
|
|
|
self.txt_result = ctk.CTkTextbox(
|
|
frame, height=200, font=self.fonts["mono_small"],
|
|
state="disabled", wrap="none",
|
|
)
|
|
self.txt_result.grid(row=1, column=0, sticky="ew", padx=15, pady=(0, 10))
|
|
|
|
# -- API pública -------------------------------------------------------------
|
|
|
|
def set_on_select_csv(self, callback):
|
|
self.btn_select_csv.configure(command=callback)
|
|
|
|
def set_on_run(self, callback):
|
|
self.btn_run.configure(command=callback)
|
|
|
|
def set_on_save(self, callback):
|
|
self.btn_save.configure(command=callback)
|
|
|
|
def set_csv_path(self, path: str):
|
|
self.lbl_csv_path.configure(text=path or "Ningún archivo seleccionado")
|
|
|
|
def get_instructions(self) -> str:
|
|
return self.txt_instructions.get("1.0", "end").strip()
|
|
|
|
def set_status(self, text: str):
|
|
self.lbl_status.configure(text=text)
|
|
|
|
def set_preview(self, text: str):
|
|
self.txt_preview.configure(state="normal")
|
|
self.txt_preview.delete("1.0", "end")
|
|
self.txt_preview.insert("1.0", text)
|
|
self.txt_preview.configure(state="disabled")
|
|
|
|
def set_code(self, text: str):
|
|
self.txt_code.configure(state="normal")
|
|
self.txt_code.delete("1.0", "end")
|
|
self.txt_code.insert("1.0", text)
|
|
self.txt_code.configure(state="disabled")
|
|
|
|
def append_log(self, text: str):
|
|
self.txt_log.configure(state="normal")
|
|
self.txt_log.insert("end", text + "\n")
|
|
self.txt_log.see("end")
|
|
self.txt_log.configure(state="disabled")
|
|
|
|
def clear_log(self):
|
|
self.txt_log.configure(state="normal")
|
|
self.txt_log.delete("1.0", "end")
|
|
self.txt_log.configure(state="disabled")
|
|
|
|
def set_result(self, text: str):
|
|
self.txt_result.configure(state="normal")
|
|
self.txt_result.delete("1.0", "end")
|
|
self.txt_result.insert("1.0", text)
|
|
self.txt_result.configure(state="disabled")
|
|
|
|
def enable_save(self, enabled: bool):
|
|
self.btn_save.configure(state="normal" if enabled else "disabled")
|
|
|
|
def enable_controls(self, enabled: bool):
|
|
state = "normal" if enabled else "disabled"
|
|
self.btn_select_csv.configure(state=state)
|
|
self.btn_run.configure(state=state)
|
|
self.txt_instructions.configure(state=state)
|