import { createGrid, ModuleRegistry, ValidationModule, ColumnAutoSizeModule, CellStyleModule, QuickFilterModule, RowSelectionModule, TextEditorModule, ClientSideRowModelModule, themeQuartz, iconSetQuartzLight, } from "ag-grid-community"; import { MultiFilterModule, CellSelectionModule, PivotModule, MasterDetailModule, SideBarModule, ColumnsToolPanelModule, ColumnMenuModule, StatusBarModule, ExcelExportModule, ClipboardModule, } from "ag-grid-enterprise"; import { $ } from "sigpro"; import { isDark } from "../store.js"; // ✅ Registro de módulos (UNA VEZ, fuera del componente) ModuleRegistry.registerModules([ ValidationModule, ColumnAutoSizeModule, CellStyleModule, QuickFilterModule, RowSelectionModule, TextEditorModule, ClientSideRowModelModule, MultiFilterModule, CellSelectionModule, PivotModule, MasterDetailModule, SideBarModule, ColumnsToolPanelModule, ColumnMenuModule, StatusBarModule, ExcelExportModule, ClipboardModule, ]); const getTheme = (isDark) => themeQuartz.withPart(iconSetQuartzLight).withParams({ browserColorScheme: isDark ? "dark" : "light", backgroundColor: isDark ? "#121212" : "#FDFDFD", foregroundColor: isDark ? "#E0E0E0" : "#181D1F", accentColor: isDark ? "#4FAAFF" : "#004B9C", headerBackgroundColor: isDark ? "#2A2A2A" : "#EEB111", headerTextColor: isDark ? "#4FAAFF" : "#004B9C", borderRadius: 4, columnBorder: false, headerFontSize: 14, headerFontWeight: 600, listItemHeight: 20, iconSize: 14, spacing: 3, wrapperBorderRadius: 4, }); $.component( "c-grid", (props, { onUnmount }) => { let gridApi = null; // ✅ Crear contenedor específico para este grid const container = document.createElement("div"); container.style.height = "100%"; const gridContainer = document.createElement("div"); gridContainer.style.height = "100%"; container.appendChild(gridContainer); // Theme observer const currentTheme = $(document.querySelector("[data-theme]")?.getAttribute("data-theme") || "light"); const observer = new MutationObserver(() => { const theme = document.querySelector("[data-theme]")?.getAttribute("data-theme"); if (theme !== currentTheme()) currentTheme(theme); }); observer.observe(document.documentElement, { attributes: true, subtree: true, attributeFilter: ["data-theme"], }); // ✅ LIMPIEZA COMPLETA onUnmount(() => { observer.disconnect(); // 1. Destruir el grid if (gridApi) { gridApi.destroy(); gridApi = null; } // 2. Eliminar el contenedor del DOM if (gridContainer.parentNode) { gridContainer.parentNode.removeChild(gridContainer); } // 3. Limpiar referencias container.innerHTML = ""; }); // Efecto para tema y creación inicial $.effect(() => { const dark = isDark(); const agTheme = getTheme(dark); if (!gridApi) { gridApi = createGrid(gridContainer, { ...(props.options?.() || {}), theme: agTheme, rowData: props.data?.() || [], }); } else { gridApi.setGridOption("theme", agTheme); } }); // Efecto para datos $.effect(() => { const data = props.data?.(); if (gridApi && Array.isArray(data)) { gridApi.setGridOption("rowData", data); } }); return container; }, ["data", "options"], );