Files
SteelBase/public/js/database/carregador-universal.js

325 lines
13 KiB
JavaScript

/**
* CARREGADOR UNIVERSAL DE PERFIS
* Sistema que carrega automaticamente TODOS os tipos de perfis
* usando o banco de dados embutido
*/
// Configuração de mapeamento de tipos
const MAPEAMENTO_PERFIS = {
'cantoneiras': {
tbodyId: 'cantoneiras-tbody',
totalId: 'cant-total',
colunas: [
{ key: 'nome', label: 'Designação', bold: true },
{ key: 'lado_mm', label: 'Lado (mm)' },
{ key: 'espessura_mm', label: 'Espessura (mm)' },
{ key: 'peso_kg_m', label: 'Peso (kg/m)', decimals: 2 },
{ key: 'area_cm2', label: 'Área (cm²)', decimals: 2 },
{ key: 'momento_inercia_cm4', label: 'Momento Inércia (cm⁴)', decimals: 2 },
{ key: 'raio_giracao_cm', label: 'Raio Giração (cm)', decimals: 2 },
{ key: 'tipo', label: 'Categoria', badge: true }
]
},
'barras_redondas': {
tbodyId: 'barras_redondas-tbody',
totalId: 'barras_redondas-total',
colunas: [
{ key: 'nome', label: 'Designação', bold: true },
{ key: 'diametro_mm', label: 'Diâmetro (mm)' },
{ key: 'peso_kg_m', label: 'Peso (kg/m)', decimals: 3 },
{ key: 'area_cm2', label: 'Área (cm²)', decimals: 3 },
{ key: 'momento_inercia_cm4', label: 'Momento Inércia (cm⁴)', decimals: 2 },
{ key: 'raio_giracao_cm', label: 'Raio Giração (cm)', decimals: 2 },
{ key: 'aplicacao', label: 'Aplicação' },
{ key: 'tipo', label: 'Categoria', badge: true }
]
},
'tubos_circulares': {
tbodyId: 'tubos_circulares-tbody',
totalId: 'tubos_circulares-total',
colunas: [
{ key: 'nome', label: 'Designação', bold: true },
{ key: 'diametro_mm', label: 'Ø Externo (mm)' },
{ key: 'espessura_mm', label: 'Espessura (mm)' },
{ key: 'peso_kg_m', label: 'Peso (kg/m)', decimals: 2 },
{ key: 'area_cm2', label: 'Área (cm²)', decimals: 2 },
{ key: 'momento_inercia_cm4', label: 'Momento Inércia (cm⁴)', decimals: 2 },
{ key: 'raio_giracao_cm', label: 'Raio Giração (cm)', decimals: 2 },
{ key: 'aplicacao', label: 'Aplicação' },
{ key: 'tipo', label: 'Categoria', badge: true }
]
},
'perfis_i': {
tbodyId: 'perfis_i-tbody',
totalId: 'perfis_i-total',
colunas: [
{ key: 'nome', label: 'Designação', bold: true },
{ key: 'altura_mm', label: 'Altura (mm)' },
{ key: 'largura_mm', label: 'Largura (mm)' },
{ key: 'espessura_alma_mm', label: 'Esp. Alma (mm)' },
{ key: 'espessura_mesa_mm', label: 'Esp. Mesa (mm)' },
{ key: 'peso_kg_m', label: 'Peso (kg/m)', decimals: 2 },
{ key: 'area_cm2', label: 'Área (cm²)', decimals: 2 },
{ key: 'tipo', label: 'Categoria', badge: true }
]
},
'perfis_w': {
tbodyId: 'perfis_w-tbody',
totalId: 'perfis_w-total',
colunas: [
{ key: 'nome', label: 'Designação', bold: true },
{ key: 'altura_mm', label: 'Altura (mm)' },
{ key: 'largura_mm', label: 'Largura (mm)' },
{ key: 'espessura_alma_mm', label: 'Esp. Alma (mm)' },
{ key: 'espessura_mesa_mm', label: 'Esp. Mesa (mm)' },
{ key: 'peso_kg_m', label: 'Peso (kg/m)', decimals: 2 },
{ key: 'area_cm2', label: 'Área (cm²)', decimals: 2 },
{ key: 'tipo', label: 'Categoria', badge: true }
]
},
'tubos_rhs': {
tbodyId: 'tubos_rhs-tbody',
totalId: 'tubos_rhs-total',
colunas: [
{ key: 'nome', label: 'Designação', bold: true },
{ key: 'largura_mm', label: 'Largura (mm)' },
{ key: 'altura_mm', label: 'Altura (mm)' },
{ key: 'espessura_mm', label: 'Espessura (mm)' },
{ key: 'peso_kg_m', label: 'Peso (kg/m)', decimals: 2 },
{ key: 'area_cm2', label: 'Área (cm²)', decimals: 2 },
{ key: 'tipo', label: 'Categoria', badge: true }
]
},
'chapas': {
tbodyId: 'chapas-tbody',
totalId: 'chapas-total',
colunas: [
{ key: 'nome', label: 'Designação', bold: true },
{ key: 'espessura_mm', label: 'Espessura (mm)' },
{ key: 'peso_kg_m2', label: 'Peso (kg/m²)', decimals: 2 },
{ key: 'tipo', label: 'Categoria', badge: true }
]
},
'perfis_hp': {
tbodyId: 'perfis_hp-tbody',
totalId: 'perfis_hp-total',
colunas: [
{ key: 'nome', label: 'Designação', bold: true },
{ key: 'altura_mm', label: 'Altura (mm)' },
{ key: 'aba_mm', label: 'Aba (mm)' },
{ key: 'espessura_alma_mm', label: 'Esp. Alma (mm)', decimals: 1 },
{ key: 'espessura_aba_mm', label: 'Esp. Aba (mm)', decimals: 1 },
{ key: 'peso_kg_m', label: 'Peso (kg/m)', decimals: 1 },
{ key: 'area_cm2', label: 'Área (cm²)', decimals: 1 },
{ key: 'tipo', label: 'Categoria', badge: true }
]
},
'barras_roscadas': {
tbodyId: 'barras_roscadas-tbody',
totalId: 'barras_roscadas-total',
colunas: [
{ key: 'tipo_rosca', label: 'Tipo', badge: true },
{ key: 'diametro_nominal_mm', label: 'Diâmetro (mm)', decimals: 2 },
{ key: 'passo_mm', label: 'Passo (mm)', decimals: 2 },
{ key: 'peso_kg_m', label: 'Peso (kg/m)', decimals: 3 },
{ key: 'aplicacao', label: 'Aplicação' },
{ key: 'tamanho', label: 'Categoria', badge: true }
]
},
'barras_chatas': {
tbodyId: 'barras_chatas-tbody',
totalId: 'barras_chatas-total',
colunas: [
{ key: 'nome', label: 'Designação', bold: true },
{ key: 'largura_mm', label: 'Largura (mm)', decimals: 1 },
{ key: 'espessura_mm', label: 'Espessura (mm)', decimals: 1 },
{ key: 'peso_kg_m', label: 'Peso (kg/m)', decimals: 3 },
{ key: 'area_cm2', label: 'Área (cm²)', decimals: 2 },
{ key: 'tamanho', label: 'Categoria', badge: true }
]
}
};
/**
* Carrega dados de um tipo específico de perfil
*/
function carregarPerfilUniversal(tipo) {
console.log(`🚀 Carregando perfil: ${tipo}`);
const config = MAPEAMENTO_PERFIS[tipo];
if (!config) {
console.error(`❌ Configuração não encontrada para: ${tipo}`);
return false;
}
const tbody = document.getElementById(config.tbodyId);
if (!tbody) {
console.warn(`⚠️ Elemento ${config.tbodyId} não encontrado`);
return false;
}
// Obter dados do banco
const dados = window.BANCO_DADOS_PERFIS?.[tipo];
if (!dados || dados.length === 0) {
console.error(`❌ Dados não encontrados para: ${tipo}`);
tbody.innerHTML = `
<tr>
<td colspan="${config.colunas.length + 1}" style="text-align: center; padding: 40px;">
<div style="font-size: 48px; margin-bottom: 16px;">❌</div>
<div style="font-size: 18px; font-weight: bold; color: #ef4444;">Dados não encontrados</div>
<div style="font-size: 14px; color: #666; margin-top: 8px;">Tipo: ${tipo}</div>
</td>
</tr>
`;
return false;
}
// Gerar HTML da tabela
const html = dados.map(item => {
const colunas = config.colunas.map(col => {
let valor = item[col.key];
// Formatação
if (col.decimals && typeof valor === 'number') {
valor = valor.toFixed(col.decimals);
}
// Estilo
if (col.bold) {
return `<td><strong>${valor}</strong></td>`;
} else if (col.badge) {
return `<td><span class="badge badge-info">${valor}</span></td>`;
} else {
return `<td>${valor}</td>`;
}
}).join('');
return `<tr>${colunas}<td><button class="btn btn-sm btn-primary">👁️ Ver</button></td></tr>`;
}).join('');
tbody.innerHTML = html;
// Atualizar contador
const totalEl = document.getElementById(config.totalId);
if (totalEl) {
totalEl.textContent = dados.length;
}
// Armazenar globalmente
window[`${tipo}Data`] = dados;
console.log(`${tipo}: ${dados.length} itens carregados`);
return true;
}
/**
* Observer universal que detecta qualquer tabela de perfil
*/
function iniciarObserverUniversal() {
console.log('👁️ Iniciando observer universal para todos os perfis');
const observer = new MutationObserver((mutations) => {
// Verificar cada tipo de perfil
Object.keys(MAPEAMENTO_PERFIS).forEach(tipo => {
const config = MAPEAMENTO_PERFIS[tipo];
const tbody = document.getElementById(config.tbodyId);
if (tbody) {
// Verificar se está vazio
const conteudo = tbody.textContent.trim();
const estaVazio = tbody.children.length === 0 ||
conteudo.includes('Será preenchido') ||
conteudo.includes('preenchido via JavaScript') ||
(tbody.children.length === 1 && tbody.children[0].children.length === 1);
if (estaVazio) {
console.log(`🎯 Tabela vazia detectada: ${tipo}`);
// Aguardar um pouco e carregar
setTimeout(() => {
const sucesso = carregarPerfilUniversal(tipo);
if (sucesso) {
console.log(`✅ Auto-carregamento concluído: ${tipo}`);
}
}, 300);
}
}
});
});
// Observar mudanças no body
observer.observe(document.body, {
childList: true,
subtree: true
});
// Tentar carregar imediatamente também
setTimeout(() => {
Object.keys(MAPEAMENTO_PERFIS).forEach(tipo => {
const config = MAPEAMENTO_PERFIS[tipo];
const tbody = document.getElementById(config.tbodyId);
if (tbody) {
carregarPerfilUniversal(tipo);
}
});
}, 1000);
console.log('✅ Observer universal ativo para todos os perfis');
}
// Gerar funções de carregamento forçado para cada tipo
Object.keys(MAPEAMENTO_PERFIS).forEach(tipo => {
const funcName = `forcarCarregamento${tipo.split('_').map(word =>
word.charAt(0).toUpperCase() + word.slice(1)
).join('')}`;
window[funcName] = function() {
console.log(`🚨 Carregamento forçado: ${tipo}`);
const config = MAPEAMENTO_PERFIS[tipo];
const tbody = document.getElementById(config.tbodyId);
if (!tbody) {
alert(`❌ Erro: Tabela não encontrada para ${tipo}`);
return;
}
// Mostrar loading
tbody.innerHTML = `
<tr>
<td colspan="${config.colunas.length + 1}" style="text-align: center; padding: 40px;">
<div style="font-size: 48px; margin-bottom: 16px;">⏳</div>
<div style="font-size: 18px; font-weight: bold;">Carregando ${tipo}...</div>
</td>
</tr>
`;
// Carregar após delay
setTimeout(() => {
const sucesso = carregarPerfilUniversal(tipo);
if (sucesso) {
const dados = window.BANCO_DADOS_PERFIS[tipo];
alert(`${dados.length} ${tipo} carregados com sucesso!`);
} else {
alert(`❌ Erro ao carregar ${tipo}`);
}
}, 500);
};
console.log(`✅ Função criada: ${funcName}`);
});
// Inicializar quando DOM estiver pronto
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', iniciarObserverUniversal);
} else {
iniciarObserverUniversal();
}
// Exportar funções
window.carregarPerfilUniversal = carregarPerfilUniversal;
window.MAPEAMENTO_PERFIS = MAPEAMENTO_PERFIS;
console.log('✅ Carregador universal configurado para todos os perfis');
console.log('📊 Perfis suportados:', Object.keys(MAPEAMENTO_PERFIS));