2025-03-07 00:29:07 -06:00

246 lines
9.0 KiB
JavaScript

import '../../vendor/libs/bootstrap-table/bootstrap-table';
import '../notifications/LivewireNotification';
class BootstrapTableManager {
constructor(bootstrapTableWrap, config = {}) {
const defaultConfig = {
header: [],
format: [],
search_columns: [],
actionColumn: false,
height: 'auto',
minHeight: 300,
bottomMargin : 195,
search: true,
showColumns: true,
showColumnsToggleAll: true,
showExport: true,
exportfileName: 'datatTable',
exportWithDatetime: true,
showFullscreen: true,
showPaginationSwitch: true,
showRefresh: true,
showToggle: true,
/*
smartDisplay: false,
searchOnEnterKey: true,
showHeader: false,
showFooter: true,
showRefresh: true,
showToggle: true,
showFullscreen: true,
detailView: true,
searchAlign: 'right',
buttonsAlign: 'right',
toolbarAlign: 'left',
paginationVAlign: 'bottom',
paginationHAlign: 'right',
paginationDetailHAlign: 'left',
paginationSuccessivelySize: 5,
paginationPagesBySide: 3,
paginationUseIntermediate: true,
*/
clickToSelect: true,
minimumCountColumns: 4,
fixedColumns: true,
fixedNumber: 1,
idField: 'id',
pagination: true,
pageList: [25, 50, 100, 500, 1000],
sortName: 'id',
sortOrder: 'asc',
cookie: false,
cookieExpire: '365d',
cookieIdTable: 'myTableCookies', // Nombre único para las cookies de la tabla
cookieStorage: 'localStorage',
cookiePath: '/',
};
this.$bootstrapTable = $('.bootstrap-table', bootstrapTableWrap);
this.$toolbar = $('.bt-toolbar', bootstrapTableWrap);
this.$searchColumns = $('.search_columns', bootstrapTableWrap);
this.$btnRefresh = $('.btn-refresh', bootstrapTableWrap);
this.$btnClearFilters = $('.btn-clear-filters', bootstrapTableWrap);
this.config = { ...defaultConfig, ...config };
this.config.toolbar = `${bootstrapTableWrap} .bt-toolbar`;
this.config.height = this.config.height == 'auto'? this.getTableHeight(): this.config.height;
this.config.cookieIdTable = this.config.exportWithDatetime? this.config.cookieIdTable + '-' + this.getFormattedDateYMDHm(): this.config.cookieIdTable;
this.tableFormatters = {}; // Mueve la carga de formatters aquí
this.initTable();
}
/**
* Calcula la altura de la tabla.
*/
getTableHeight() {
const btHeight = window.innerHeight - this.$toolbar.height() - this.bottomMargin;
return btHeight < this.config.minHeight ? this.config.minHeight : btHeight;
}
/**
* Genera un ID único para la tabla basado en una cookie.
*/
getCookieId() {
const generateShortHash = (str) => {
let hash = 0;
for (let i = 0; i < str.length; i++) {
const char = str.charCodeAt(i);
hash = (hash << 5) - hash + char;
hash &= hash; // Convertir a entero de 32 bits
}
return Math.abs(hash).toString().substring(0, 12);
};
return `bootstrap-table-cache-${generateShortHash(this.config.title)}`;
}
/**
* Carga los formatters dinámicamente
*/
async loadFormatters() {
const formattersModules = import.meta.glob('../../../../../**/resources/assets/js/bootstrap-table/*Formatters.js');
const formatterPromises = Object.entries(formattersModules).map(async ([path, importer]) => {
const module = await importer();
Object.assign(this.tableFormatters, module);
});
await Promise.all(formatterPromises);
}
btColumns() {
const columns = [];
Object.entries(this.config.header).forEach(([key, value]) => {
const columnFormat = this.config.format[key] || {};
if (typeof columnFormat.formatter === 'object') {
const formatterName = columnFormat.formatter.name;
const formatterParams = columnFormat.formatter.params || {};
const formatterFunction = this.tableFormatters[formatterName];
if (formatterFunction) {
columnFormat.formatter = (value, row, index) => formatterFunction(value, row, index, formatterParams);
} else {
console.warn(`Formatter "${formatterName}" no encontrado para la columna "${key}"`);
}
} else if (typeof columnFormat.formatter === 'string') {
const formatterFunction = this.tableFormatters[columnFormat.formatter];
if (formatterFunction) {
columnFormat.formatter = formatterFunction;
}
}
if (columnFormat.onlyFormatter) {
columns.push({
align: 'center',
formatter: columnFormat.formatter || (() => ''),
forceHide: true,
switchable: false,
field: key,
title: value,
});
return;
}
const column = {
title: value,
field: key,
sortable: true,
};
columns.push({ ...column, ...columnFormat });
});
return columns;
}
/**
* Petición AJAX para la tabla.
*/
ajaxRequest(params) {
const url = `${window.location.href}?${$.param(params.data)}&${$('.bt-toolbar :input').serialize()}`;
$.get(url).then((res) => params.success(res));
}
toValidFilename(str, extension = 'txt') {
return str
.normalize("NFD") // 🔹 Normaliza caracteres con tilde
.replace(/[\u0300-\u036f]/g, "") // 🔹 Elimina acentos y diacríticos
.replace(/[<>:"\/\\|?*\x00-\x1F]/g, '') // 🔹 Elimina caracteres inválidos
.replace(/\s+/g, '-') // 🔹 Reemplaza espacios con guiones
.replace(/-+/g, '-') // 🔹 Evita múltiples guiones seguidos
.replace(/^-+|-+$/g, '') // 🔹 Elimina guiones al inicio y fin
.toLowerCase() // 🔹 Convierte a minúsculas
+ (extension ? '.' + extension.replace(/^\.+/, '') : ''); // 🔹 Asegura la extensión válida
}
getFormattedDateYMDHm(date = new Date()) {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0'); // 🔹 Asegura dos dígitos
const day = String(date.getDate()).padStart(2, '0');
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
return `${year}${month}${day}-${hours}${minutes}`;
}
/**
* Inicia la tabla después de cargar los formatters
*/
async initTable() {
await this.loadFormatters(); // Asegura que los formatters estén listos antes de inicializar
this.$bootstrapTable
.bootstrapTable('destroy').bootstrapTable({
height: this.config.height,
locale: 'es-MX',
ajax: (params) => this.ajaxRequest(params),
toolbar: this.config.toolbar,
search: this.config.search,
showColumns: this.config.showColumns,
showColumnsToggleAll: this.config.showColumnsToggleAll,
showExport: this.config.showExport,
exportTypes: ['csv', 'txt', 'xlsx'],
exportOptions: {
fileName: this.config.fileName,
},
showFullscreen: this.config.showFullscreen,
showPaginationSwitch: this.config.showPaginationSwitch,
showRefresh: this.config.showRefresh,
showToggle: this.config.showToggle,
clickToSelect: this.config.clickToSelect,
minimumCountColumns: this.config.minimumCountColumns,
fixedColumns: this.config.fixedColumns,
fixedNumber: this.config.fixedNumber,
idField: this.config.idField,
pagination: this.config.pagination,
pageList: this.config.pageList,
sidePagination: "server",
sortName: this.config.sortName,
sortOrder: this.config.sortOrder,
mobileResponsive: true,
resizable: true,
cookie: this.config.cookie,
cookieExpire: this.config.cookieExpire,
cookieIdTable: this.config.cookieIdTable,
columns: this.btColumns(),
});
}
}
window.BootstrapTableManager = BootstrapTableManager;