Files
Dare2/components_/AgGrid.js
2026-03-25 02:03:59 +01:00

143 lines
3.4 KiB
JavaScript

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"],
);