small changes
This commit is contained in:
170
grid/index.js
170
grid/index.js
@@ -1,66 +1,130 @@
|
||||
/** GRID */
|
||||
export const Grid = (props, lang) => {
|
||||
const { data, options, api, on, class: className } = props;
|
||||
let gridApi = null;
|
||||
const { data, options, api, on, class: className, style = "height: 100%; width: 100%;" } = props;
|
||||
let gridApi = null;
|
||||
|
||||
return $html("div", {
|
||||
style: "height: 100%; width: 100%;",
|
||||
class: className,
|
||||
ref: async (container) => {
|
||||
const { createGrid } = await import("./grid/grid.js");
|
||||
const isDark = () => {
|
||||
return document.documentElement.getAttribute('data-theme') === 'dark' ||
|
||||
window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
};
|
||||
|
||||
const initialData = typeof data === "function" ? data() : data;
|
||||
const initialOptions = typeof options === "function" ? options() : options;
|
||||
const getTheme = (dark) => {
|
||||
return dark ? 'ag-theme-alpine-dark' : 'ag-theme-alpine';
|
||||
};
|
||||
|
||||
const gridOptions = {
|
||||
...initialOptions,
|
||||
theme: getTheme(isDark()),
|
||||
rowData: initialData || [],
|
||||
onGridReady: (params) => {
|
||||
gridApi = params.api;
|
||||
if (api) api.current = gridApi;
|
||||
if (on?.onGridReady) on.onGridReady(params);
|
||||
},
|
||||
onFilterChanged: (e) => on?.onFilterChanged?.(e),
|
||||
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)
|
||||
};
|
||||
return $html("div", {
|
||||
style,
|
||||
class: className,
|
||||
ref: async (container) => {
|
||||
try {
|
||||
const { createGrid } = await import("./grid.js");
|
||||
|
||||
gridApi = createGrid(container, gridOptions);
|
||||
const initialData = typeof data === "function" ? data() : data;
|
||||
const initialOptions = typeof options === "function" ? options() : options;
|
||||
|
||||
const stopData = $watch(() => {
|
||||
const rowData = typeof data === "function" ? data() : data;
|
||||
if (gridApi && Array.isArray(rowData)) {
|
||||
gridApi.setGridOption("rowData", rowData);
|
||||
// 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 = {
|
||||
...initialOptions,
|
||||
theme: getTheme(isDark()),
|
||||
rowData: initialData || [],
|
||||
onGridReady: (params) => {
|
||||
gridApi = params.api;
|
||||
if (api) api.current = gridApi;
|
||||
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);
|
||||
}
|
||||
},
|
||||
...eventHandlers
|
||||
};
|
||||
|
||||
const stopTheme = $watch(() => {
|
||||
const dark = isDark();
|
||||
if (gridApi) gridApi.setGridOption("theme", getTheme(dark));
|
||||
});
|
||||
gridApi = createGrid(container, gridOptions);
|
||||
|
||||
container._cleanups.add(stopData);
|
||||
container._cleanups.add(stopTheme);
|
||||
container._cleanups.add(() => {
|
||||
if (gridApi) {
|
||||
gridApi.destroy();
|
||||
if (api) api.current = null;
|
||||
gridApi = null;
|
||||
// Watch para cambios en los datos
|
||||
const stopData = $watch(() => {
|
||||
const newData = typeof data === "function" ? data() : data;
|
||||
if (gridApi && !gridApi.isDestroyed() && Array.isArray(newData)) {
|
||||
const currentData = gridApi.getGridOption("rowData");
|
||||
if (newData !== currentData) {
|
||||
gridApi.setGridOption("rowData", newData);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Watch para cambios de tema
|
||||
const stopTheme = $watch(() => {
|
||||
if (gridApi && !gridApi.isDestroyed()) {
|
||||
const dark = isDark();
|
||||
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(stopTheme);
|
||||
container._cleanups.add(stopOptions);
|
||||
container._cleanups.add(() => {
|
||||
if (gridApi && !gridApi.isDestroyed()) {
|
||||
gridApi.destroy();
|
||||
if (api) api.current = 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>`;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
Reference in New Issue
Block a user