350 lines
14 KiB
JavaScript
350 lines
14 KiB
JavaScript
/**
|
||
* CARREGADOR AUTOMÁTICO PARA TODOS OS PERFIS
|
||
* Gera automaticamente as funções de carregamento para cada tipo de perfil
|
||
*/
|
||
|
||
/**
|
||
* Gera função de carregamento forçado para um tipo de perfil
|
||
*/
|
||
function gerarFuncaoCarregamento(tipo) {
|
||
const config = window.PERFIS_CONFIG[tipo];
|
||
if (!config) return null;
|
||
|
||
const tipoId = tipo.replace(/-/g, '_');
|
||
const funcName = `forcarCarregamento${capitalize(tipoId)}`;
|
||
|
||
window[funcName] = async function() {
|
||
console.log(`🚨 CARREGAMENTO FORÇADO INICIADO: ${config.nome}`);
|
||
|
||
const tbody = document.getElementById(`${tipoId}-tbody`);
|
||
if (!tbody) {
|
||
alert(`❌ Erro: Elemento da tabela não encontrado!`);
|
||
console.error(`❌ Elemento ${tipoId}-tbody não encontrado`);
|
||
return;
|
||
}
|
||
|
||
// Mostrar loading
|
||
tbody.innerHTML = `
|
||
<tr>
|
||
<td colspan="${config.colunasTabel.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 dados...</div>
|
||
<div style="font-size: 14px; color: #666; margin-top: 8px;">Aguarde alguns segundos</div>
|
||
</td>
|
||
</tr>
|
||
`;
|
||
|
||
try {
|
||
// Carregar CSV
|
||
console.log(`📥 Carregando CSV: ${config.csv}`);
|
||
const response = await fetch(config.csv);
|
||
|
||
if (!response.ok) {
|
||
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
||
}
|
||
|
||
const csvText = await response.text();
|
||
const linhas = csvText.trim().split('\n');
|
||
|
||
console.log(`📊 CSV carregado: ${linhas.length} linhas`);
|
||
|
||
// Processar dados
|
||
const dados = [];
|
||
for (let i = 1; i < linhas.length; i++) {
|
||
const linha = linhas[i].trim();
|
||
if (!linha) continue;
|
||
|
||
const colunas = linha.split(',');
|
||
if (colunas.length >= config.colunas.length) {
|
||
const item = {};
|
||
config.colunas.forEach((col, index) => {
|
||
let value = colunas[index].trim();
|
||
// Converter números
|
||
if (col.includes('_mm') || col.includes('_kg') || col.includes('_cm') || col.includes('_m2')) {
|
||
value = parseFloat(value) || 0;
|
||
}
|
||
item[col] = value;
|
||
});
|
||
dados.push(item);
|
||
}
|
||
}
|
||
|
||
console.log(`✅ Processados: ${dados.length} itens`);
|
||
|
||
if (dados.length === 0) {
|
||
throw new Error('Nenhum dado encontrado no CSV');
|
||
}
|
||
|
||
// Exibir na tabela
|
||
tbody.innerHTML = dados.map(item => `
|
||
<tr>
|
||
${config.colunasTabel.map(col => {
|
||
let value = item[col.key];
|
||
if (col.decimals && typeof value === 'number') {
|
||
value = value.toFixed(col.decimals);
|
||
}
|
||
if (col.badge) {
|
||
return `<td><span class="badge badge-info">${value}</span></td>`;
|
||
}
|
||
return `<td>${col.key === 'nome' ? '<strong>' + value + '</strong>' : value}</td>`;
|
||
}).join('')}
|
||
<td><button class="btn btn-sm btn-primary">👁️ Ver</button></td>
|
||
</tr>
|
||
`).join('');
|
||
|
||
// Atualizar contador
|
||
const totalEl = document.getElementById(`${tipoId}-total`);
|
||
if (totalEl) {
|
||
totalEl.textContent = dados.length;
|
||
}
|
||
|
||
// Armazenar globalmente
|
||
window[`${tipoId}Data`] = dados;
|
||
|
||
console.log(`🎉 CARREGAMENTO CONCLUÍDO: ${config.nome}`);
|
||
|
||
// Notificar usuário
|
||
alert(`✅ ${dados.length} ${config.nome.toLowerCase()} carregados com sucesso!`);
|
||
|
||
} catch (error) {
|
||
console.error(`❌ Erro no carregamento: ${error.message}`);
|
||
|
||
tbody.innerHTML = `
|
||
<tr>
|
||
<td colspan="${config.colunasTabel.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;">Erro ao carregar dados</div>
|
||
<div style="font-size: 14px; color: #666; margin-top: 8px;">${error.message}</div>
|
||
<button class="btn btn-primary" onclick="${funcName}()" style="margin-top: 16px;">
|
||
🔄 Tentar Novamente
|
||
</button>
|
||
</td>
|
||
</tr>
|
||
`;
|
||
|
||
alert(`❌ Erro ao carregar dados: ${error.message}`);
|
||
}
|
||
};
|
||
|
||
console.log(`✅ Função criada: ${funcName}`);
|
||
}
|
||
|
||
/**
|
||
* Gera funções de filtro para um tipo de perfil
|
||
*/
|
||
function gerarFuncoesFiltro(tipo) {
|
||
const config = window.PERFIS_CONFIG[tipo];
|
||
if (!config) return;
|
||
|
||
const tipoId = tipo.replace(/-/g, '_');
|
||
|
||
// Função de filtrar
|
||
window[`filtrar${capitalize(tipoId)}`] = function() {
|
||
const dados = window[`${tipoId}Data`];
|
||
if (!dados) {
|
||
console.warn('⚠️ Dados não carregados ainda');
|
||
return;
|
||
}
|
||
|
||
// Implementar filtros básicos
|
||
console.log(`🔍 Filtrando ${config.nome}...`);
|
||
// TODO: Implementar lógica de filtro
|
||
};
|
||
|
||
// Função de limpar filtros
|
||
window[`limparFiltros${capitalize(tipoId)}`] = function() {
|
||
console.log(`🧹 Limpando filtros de ${config.nome}`);
|
||
|
||
// Limpar campos
|
||
config.filtros.forEach(filtro => {
|
||
const el = document.getElementById(`${tipoId}-${filtro.id}`);
|
||
if (el) el.value = '';
|
||
});
|
||
|
||
// Reexibir todos os dados
|
||
const dados = window[`${tipoId}Data`];
|
||
if (dados) {
|
||
const tbody = document.getElementById(`${tipoId}-tbody`);
|
||
if (tbody) {
|
||
tbody.innerHTML = dados.map(item => `
|
||
<tr>
|
||
${config.colunasTabel.map(col => {
|
||
let value = item[col.key];
|
||
if (col.decimals && typeof value === 'number') {
|
||
value = value.toFixed(col.decimals);
|
||
}
|
||
if (col.badge) {
|
||
return `<td><span class="badge badge-info">${value}</span></td>`;
|
||
}
|
||
return `<td>${col.key === 'nome' ? '<strong>' + value + '</strong>' : value}</td>`;
|
||
}).join('')}
|
||
<td><button class="btn btn-sm btn-primary">👁️ Ver</button></td>
|
||
</tr>
|
||
`).join('');
|
||
}
|
||
}
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Gera função de conteúdo para um tipo de perfil
|
||
*/
|
||
function gerarFuncaoConteudo(tipo) {
|
||
const config = window.PERFIS_CONFIG[tipo];
|
||
if (!config) return;
|
||
|
||
const funcName = `get${capitalize(tipo.replace(/-/g, '_'))}Content`;
|
||
|
||
window[funcName] = function() {
|
||
console.log(`🔧 ${funcName}() chamada`);
|
||
return gerarConteudoPerfil(tipo);
|
||
};
|
||
|
||
console.log(`✅ Função criada: ${funcName}`);
|
||
}
|
||
|
||
/**
|
||
* Inicializa todas as funções para todos os perfis
|
||
*/
|
||
function inicializarTodosPerfis() {
|
||
console.log('🚀 Inicializando funções para todos os perfis...');
|
||
|
||
Object.keys(window.PERFIS_CONFIG).forEach(tipo => {
|
||
gerarFuncaoConteudo(tipo);
|
||
gerarFuncaoCarregamento(tipo);
|
||
gerarFuncoesFiltro(tipo);
|
||
gerarFuncaoAtualizarFonte(tipo);
|
||
});
|
||
|
||
console.log('✅ Todas as funções de perfis inicializadas!');
|
||
}
|
||
|
||
/**
|
||
* Capitaliza primeira letra
|
||
*/
|
||
function capitalize(str) {
|
||
return str.split('_').map(word =>
|
||
word.charAt(0).toUpperCase() + word.slice(1)
|
||
).join('');
|
||
}
|
||
|
||
// Inicializar quando o script carregar
|
||
if (document.readyState === 'loading') {
|
||
document.addEventListener('DOMContentLoaded', inicializarTodosPerfis);
|
||
} else {
|
||
inicializarTodosPerfis();
|
||
}
|
||
|
||
console.log('✅ Auto-loader de perfis carregado');
|
||
|
||
// ========================================
|
||
// Atualização direta a partir da fonte (CSV)
|
||
// ========================================
|
||
|
||
/**
|
||
* Mapeia o ID do template (com hífen) para a chave do DataManager (com underscore)
|
||
*/
|
||
function mapToDataManagerKey(tipo) {
|
||
return tipo.replace(/-/g, '_');
|
||
}
|
||
|
||
/**
|
||
* Gera função de atualização de dados a partir da fonte oficial (DataManager)
|
||
* Cria window["atualizarFonte<Cap>"] para cada tipo. O botão existe apenas em Tubos RHS.
|
||
*/
|
||
function gerarFuncaoAtualizarFonte(tipo) {
|
||
const config = window.PERFIS_CONFIG[tipo];
|
||
if (!config) return;
|
||
const tipoId = tipo.replace(/-/g, '_');
|
||
const funcName = `atualizarFonte${capitalize(tipoId)}`;
|
||
const dmKey = mapToDataManagerKey(tipo);
|
||
|
||
window[funcName] = async function() {
|
||
try {
|
||
const tbody = document.getElementById(`${tipoId}-tbody`);
|
||
const tableContainer = document.getElementById(`${tipoId}-table-container`);
|
||
if (!tbody || !tableContainer) {
|
||
alert('❌ Elementos da tabela não encontrados.');
|
||
return;
|
||
}
|
||
|
||
// Loader visual
|
||
tbody.innerHTML = `
|
||
<tr>
|
||
<td colspan="${config.colunasTabel.length + 1}" style="text-align:center; padding:32px;">
|
||
<div style="font-size:42px;">⏳</div>
|
||
<div style="margin-top:8px; color: var(--color-text-secondary);">Atualizando da fonte: ${config.csv}</div>
|
||
</td>
|
||
</tr>
|
||
`;
|
||
|
||
// Atualizar via DataManager para registrar metadados e cache
|
||
const result = await window.dataManager.updateTypeData(dmKey);
|
||
const dados = result.data || [];
|
||
|
||
if (!dados.length) {
|
||
throw new Error('Fonte retornou 0 itens');
|
||
}
|
||
|
||
// Preencher tabela com os novos dados
|
||
tbody.innerHTML = dados.map(item => `
|
||
<tr>
|
||
${config.colunasTabel.map(col => {
|
||
let value = item[col.key];
|
||
if (col.decimals && typeof value === 'number') {
|
||
value = value.toFixed(col.decimals);
|
||
}
|
||
if (col.badge) {
|
||
return `<td><span class="badge badge-info">${value}</span></td>`;
|
||
}
|
||
return `<td>${col.key === 'nome' ? '<strong>' + value + '</strong>' : value}</td>`;
|
||
}).join('')}
|
||
<td><button class="btn btn-sm btn-primary">👁️ Ver</button></td>
|
||
</tr>
|
||
`).join('');
|
||
|
||
// Atualizar contadores e metadados visuais
|
||
const totalEl = document.getElementById(`${tipoId}-total`);
|
||
const fonteEl = document.getElementById(`${tipoId}-fonte`);
|
||
const lastEl = document.getElementById(`${tipoId}-last`);
|
||
if (totalEl) totalEl.textContent = dados.length;
|
||
if (fonteEl) fonteEl.textContent = result.source || config.csv;
|
||
if (lastEl) lastEl.textContent = new Date(result.lastUpdate || Date.now()).toLocaleString('pt-BR');
|
||
|
||
// Atualizar descrição do cabeçalho (quantidade)
|
||
const headerDesc = document.querySelector('.section-description');
|
||
if (headerDesc && headerDesc.textContent.includes(config.descricao)) {
|
||
headerDesc.textContent = `${config.descricao} - ${dados.length} modelos disponíveis`;
|
||
}
|
||
|
||
// Atualizar notas nas outras abas (preços, especificações, fabricantes, aplicações)
|
||
['perfil-tab-1', 'perfil-tab-2', 'perfil-tab-3', 'perfil-tab-4'].forEach(tabId => {
|
||
const tab = document.getElementById(tabId);
|
||
if (tab) {
|
||
const noteId = `${tipoId}-update-note-${tabId}`;
|
||
let note = document.getElementById(noteId);
|
||
if (!note) {
|
||
note = document.createElement('div');
|
||
note.id = noteId;
|
||
note.style.marginTop = '12px';
|
||
note.style.fontSize = '12px';
|
||
note.style.color = 'var(--color-text-secondary)';
|
||
tab.appendChild(note);
|
||
}
|
||
note.textContent = `Dados atualizados (${dados.length} itens) • Fonte: ${result.source} • ${new Date(result.lastUpdate).toLocaleString('pt-BR')}`;
|
||
}
|
||
});
|
||
|
||
// Disponibilizar globalmente
|
||
window[`${tipoId}Data`] = dados;
|
||
|
||
alert(`✅ ${config.nome} atualizado da fonte com ${dados.length} itens.`);
|
||
} catch (error) {
|
||
console.error(`❌ Erro ao atualizar da fonte (${tipo}):`, error);
|
||
alert('❌ Erro ao atualizar da fonte: ' + error.message);
|
||
}
|
||
};
|
||
|
||
console.log(`✅ Função criada: ${funcName}`);
|
||
}
|