small changes

This commit is contained in:
2026-04-04 20:08:29 +02:00
parent cc7ee90864
commit f3a35fd64e

View File

@@ -1,17 +1,45 @@
/** GRID */ /** GRID */
export const Grid = (props, lang) => { export const Grid = (props, lang) => {
const { data, options, api, on, class: className } = props; const { data, options, api, on, class: className, style = "height: 100%; width: 100%;" } = props;
let gridApi = null; let gridApi = null;
const isDark = () => {
return document.documentElement.getAttribute('data-theme') === 'dark' ||
window.matchMedia('(prefers-color-scheme: dark)').matches;
};
const getTheme = (dark) => {
return dark ? 'ag-theme-alpine-dark' : 'ag-theme-alpine';
};
return $html("div", { return $html("div", {
style: "height: 100%; width: 100%;", style,
class: className, class: className,
ref: async (container) => { ref: async (container) => {
const { createGrid } = await import("./grid/grid.js"); try {
const { createGrid } = await import("./grid.js");
const initialData = typeof data === "function" ? data() : data; const initialData = typeof data === "function" ? data() : data;
const initialOptions = typeof options === "function" ? options() : options; const initialOptions = typeof options === "function" ? options() : options;
// Eventos comunes de AG Grid
const commonEvents = [
'onFilterChanged', 'onModelUpdated', 'onGridSizeChanged',
'onFirstDataRendered', 'onRowValueChanged', 'onSelectionChanged',
'onCellClicked', 'onCellDoubleClicked', 'onCellValueChanged',
'onRowClicked', 'onSortChanged', 'onContextMenu',
'onColumnResized', 'onColumnMoved', 'onRowDataUpdated',
'onCellEditingStarted', 'onCellEditingStopped',
'onPaginationChanged', 'onBodyScroll'
];
const eventHandlers = {};
commonEvents.forEach(eventName => {
if (on?.[eventName]) {
eventHandlers[eventName] = (params) => on[eventName](params);
}
});
const gridOptions = { const gridOptions = {
...initialOptions, ...initialOptions,
theme: getTheme(isDark()), theme: getTheme(isDark()),
@@ -20,47 +48,83 @@ export const Grid = (props, lang) => {
gridApi = params.api; gridApi = params.api;
if (api) api.current = gridApi; if (api) api.current = gridApi;
if (on?.onGridReady) on.onGridReady(params); if (on?.onGridReady) on.onGridReady(params);
if (initialOptions?.autoSizeColumns) {
setTimeout(() => {
if (gridApi && !gridApi.isDestroyed()) {
const allColumns = gridApi.getColumns();
if (allColumns?.length) {
gridApi.autoSizeColumns(allColumns);
}
}
}, 100);
}
}, },
onFilterChanged: (e) => on?.onFilterChanged?.(e), ...eventHandlers
onModelUpdated: (e) => on?.onModelUpdated?.(e),
onGridSizeChanged: (e) => on?.onGridSizeChanged?.(e),
onFirstDataRendered: (e) => on?.onFirstDataRendered?.(e),
onRowValueChanged: (e) => on?.onRowValueChanged?.(e),
onSelectionChanged: (e) => on?.onSelectionChanged?.(e),
onCellClicked: (e) => on?.onCellClicked?.(e),
onCellDoubleClicked: (e) => on?.onCellDoubleClicked?.(e),
onCellValueChanged: (e) => on?.onCellValueChanged?.(e),
onRowClicked: (e) => on?.onRowClicked?.(e),
onSortChanged: (e) => on?.onSortChanged?.(e),
onContextMenu: (e) => on?.onContextMenu?.(e),
onColumnResized: (e) => on?.onColumnResized?.(e),
onColumnMoved: (e) => on?.onColumnMoved?.(e),
onRowDataUpdated: (e) => on?.onRowDataUpdated?.(e)
}; };
gridApi = createGrid(container, gridOptions); gridApi = createGrid(container, gridOptions);
// Watch para cambios en los datos
const stopData = $watch(() => { const stopData = $watch(() => {
const rowData = typeof data === "function" ? data() : data; const newData = typeof data === "function" ? data() : data;
if (gridApi && Array.isArray(rowData)) { if (gridApi && !gridApi.isDestroyed() && Array.isArray(newData)) {
gridApi.setGridOption("rowData", rowData); const currentData = gridApi.getGridOption("rowData");
if (newData !== currentData) {
gridApi.setGridOption("rowData", newData);
}
} }
}); });
// Watch para cambios de tema
const stopTheme = $watch(() => { const stopTheme = $watch(() => {
if (gridApi && !gridApi.isDestroyed()) {
const dark = isDark(); const dark = isDark();
if (gridApi) gridApi.setGridOption("theme", getTheme(dark)); const newTheme = getTheme(dark);
const currentTheme = gridApi.getGridOption("theme");
if (newTheme !== currentTheme) {
gridApi.setGridOption("theme", newTheme);
}
}
}); });
// ⚠️ IMPORTANTE: Solo actualizar opciones seguras
// No actualizar columnDefs, rowData, o theme dinámicamente
const safeOptions = ['pagination', 'paginationPageSize', 'suppressRowClickSelection',
'rowSelection', 'enableCellTextSelection', 'ensureDomOrder',
'stopEditingWhenCellsLoseFocus', 'enterMovesDown', 'enterMovesDownAfterEdit'];
const stopOptions = $watch(() => {
if (gridApi && !gridApi.isDestroyed() && options) {
const newOptions = typeof options === "function" ? options() : options;
safeOptions.forEach(key => {
if (newOptions[key] !== undefined) {
try {
gridApi.setGridOption(key, newOptions[key]);
} catch (e) {
console.warn(`Could not set grid option ${key}:`, e);
}
}
});
}
});
// Limpieza
container._cleanups.add(stopData); container._cleanups.add(stopData);
container._cleanups.add(stopTheme); container._cleanups.add(stopTheme);
container._cleanups.add(stopOptions);
container._cleanups.add(() => { container._cleanups.add(() => {
if (gridApi) { if (gridApi && !gridApi.isDestroyed()) {
gridApi.destroy(); gridApi.destroy();
if (api) api.current = null; if (api) api.current = null;
gridApi = null; gridApi = null;
} }
}); });
} catch (error) {
console.error("Failed to initialize AG Grid:", error);
container.innerHTML = `<div class="text-error p-4">Error loading grid: ${error.message}</div>`;
}
} }
}); });
}; };