311 lines
11 KiB
JavaScript
311 lines
11 KiB
JavaScript
document.addEventListener('DOMContentLoaded', function() {
|
|
initializeNavigation();
|
|
initializeFilters();
|
|
initializeSearch();
|
|
initializeVariablesTable();
|
|
initializeSectionsTree();
|
|
initializeModal();
|
|
});
|
|
|
|
let currentTab = 'overview';
|
|
let filteredVariables = [];
|
|
|
|
function initializeNavigation() {
|
|
const navButtons = document.querySelectorAll('.nav-btn');
|
|
const tabContents = document.querySelectorAll('.tab-content');
|
|
|
|
navButtons.forEach(btn => {
|
|
btn.addEventListener('click', function() {
|
|
const tabName = this.getAttribute('data-tab');
|
|
|
|
navButtons.forEach(b => b.classList.remove('active'));
|
|
tabContents.forEach(t => t.classList.remove('active'));
|
|
|
|
this.classList.add('active');
|
|
document.getElementById(`tab-${tabName}`).classList.add('active');
|
|
currentTab = tabName;
|
|
});
|
|
});
|
|
}
|
|
|
|
function initializeFilters() {
|
|
const filterCheckboxes = document.querySelectorAll('.filters input[type="checkbox"]');
|
|
|
|
filterCheckboxes.forEach(checkbox => {
|
|
checkbox.addEventListener('change', applyFilters);
|
|
});
|
|
}
|
|
|
|
function applyFilters() {
|
|
const showCore = document.getElementById('filter-core').checked;
|
|
const showHard = document.getElementById('filter-hard').checked;
|
|
const showSoft = document.getElementById('filter-soft').checked;
|
|
|
|
const selectedPriorities = [];
|
|
document.querySelectorAll('.filter-priority:checked').forEach(cb => {
|
|
selectedPriorities.push(parseInt(cb.value));
|
|
});
|
|
|
|
filteredVariables = window.appData.variables.filter(variable => {
|
|
if (!showCore && variable.category === 'core_value') return false;
|
|
if (!showHard && variable.is_hard_constraint) return false;
|
|
if (!showSoft && !variable.is_hard_constraint && variable.category === 'factor') return false;
|
|
|
|
if (variable.priority_level && !selectedPriorities.includes(variable.priority_level)) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
});
|
|
|
|
renderVariablesTable(filteredVariables);
|
|
}
|
|
|
|
function initializeSearch() {
|
|
const searchInput = document.getElementById('search-input');
|
|
const searchFilter = document.getElementById('search-filter');
|
|
|
|
let searchTimeout;
|
|
searchInput.addEventListener('input', function() {
|
|
clearTimeout(searchTimeout);
|
|
searchTimeout = setTimeout(() => {
|
|
performSearch(this.value, searchFilter.value);
|
|
}, 300);
|
|
});
|
|
|
|
searchFilter.addEventListener('change', function() {
|
|
performSearch(searchInput.value, this.value);
|
|
});
|
|
}
|
|
|
|
function performSearch(query, filterType) {
|
|
query = query.toLowerCase().trim();
|
|
|
|
if (!query) {
|
|
applyFilters();
|
|
return;
|
|
}
|
|
|
|
const results = window.appData.variables.filter(variable => {
|
|
if (filterType === 'all' || filterType === 'variables') {
|
|
const searchableText = `${variable.name} ${variable.description}`.toLowerCase();
|
|
return searchableText.includes(query);
|
|
}
|
|
return false;
|
|
});
|
|
|
|
if (filterType === 'variables' || filterType === 'all') {
|
|
renderVariablesTable(results);
|
|
}
|
|
}
|
|
|
|
function initializeVariablesTable() {
|
|
const variables = window.appData.variables || [];
|
|
renderVariablesTable(variables);
|
|
|
|
document.getElementById('sort-name').addEventListener('click', () => sortVariables('name'));
|
|
document.getElementById('sort-freq').addEventListener('click', () => sortVariables('frequency'));
|
|
document.getElementById('sort-coeff').addEventListener('click', () => sortVariables('coefficient'));
|
|
}
|
|
|
|
function renderVariablesTable(variables) {
|
|
const container = document.getElementById('variables-table');
|
|
container.innerHTML = '';
|
|
|
|
if (!variables || variables.length === 0) {
|
|
container.innerHTML = '<div style="padding: 2rem; text-align: center; color: var(--text-secondary);">No variables found</div>';
|
|
return;
|
|
}
|
|
|
|
variables.forEach(variable => {
|
|
const row = document.createElement('div');
|
|
row.className = 'variable-row';
|
|
row.innerHTML = `
|
|
<div class="name">${variable.name}</div>
|
|
<div class="category">${variable.category}</div>
|
|
<div class="priority">
|
|
${variable.priority_level ? `<span class="priority-badge priority-${variable.priority_level}">${variable.priority_level}</span>` : '-'}
|
|
</div>
|
|
<div class="frequency">${variable.frequency}</div>
|
|
<div class="coefficient">${variable.coefficient_score.toFixed(3)}</div>
|
|
`;
|
|
|
|
row.addEventListener('click', () => showVariableDetail(variable));
|
|
container.appendChild(row);
|
|
});
|
|
}
|
|
|
|
function sortVariables(field) {
|
|
const sorted = [...filteredVariables].sort((a, b) => {
|
|
if (field === 'name') {
|
|
return a.name.localeCompare(b.name);
|
|
} else if (field === 'frequency') {
|
|
return b.frequency - a.frequency;
|
|
} else if (field === 'coefficient') {
|
|
return b.coefficient_score - a.coefficient_score;
|
|
}
|
|
return 0;
|
|
});
|
|
|
|
renderVariablesTable(sorted);
|
|
}
|
|
|
|
function initializeSectionsTree() {
|
|
const sections = window.appData.sections || [];
|
|
const container = document.getElementById('sections-tree');
|
|
|
|
if (!sections || sections.length === 0) {
|
|
container.innerHTML = '<div style="color: var(--text-secondary);">No sections available</div>';
|
|
return;
|
|
}
|
|
|
|
const treeData = buildSectionTree(sections);
|
|
renderSectionTree(treeData, container);
|
|
}
|
|
|
|
function buildSectionTree(sections) {
|
|
const sectionMap = new Map();
|
|
const roots = [];
|
|
|
|
sections.forEach(section => {
|
|
sectionMap.set(section.id, { ...section, children: [] });
|
|
});
|
|
|
|
sections.forEach(section => {
|
|
if (section.path && section.path.includes('/')) {
|
|
const parentPath = section.path.substring(0, section.path.lastIndexOf('/'));
|
|
const parent = sections.find(s => s.path === parentPath);
|
|
if (parent) {
|
|
sectionMap.get(parent.id)?.children.push(sectionMap.get(section.id));
|
|
}
|
|
} else {
|
|
roots.push(sectionMap.get(section.id));
|
|
}
|
|
});
|
|
|
|
return roots;
|
|
}
|
|
|
|
function renderSectionTree(tree, container, level = 0) {
|
|
tree.forEach(section => {
|
|
const div = document.createElement('div');
|
|
div.className = `section-item level-${level}`;
|
|
div.innerHTML = `
|
|
<div class="section-title">${section.title}</div>
|
|
${section.content ? `<div class="section-content">${section.content.substring(0, 200)}...</div>` : ''}
|
|
`;
|
|
container.appendChild(div);
|
|
|
|
if (section.children && section.children.length > 0) {
|
|
renderSectionTree(section.children, container, level + 1);
|
|
}
|
|
});
|
|
}
|
|
|
|
function initializeModal() {
|
|
const modal = document.getElementById('variable-detail-modal');
|
|
const closeBtn = modal.querySelector('.close');
|
|
|
|
closeBtn.addEventListener('click', () => {
|
|
modal.style.display = 'none';
|
|
});
|
|
|
|
window.addEventListener('click', (e) => {
|
|
if (e.target === modal) {
|
|
modal.style.display = 'none';
|
|
}
|
|
});
|
|
}
|
|
|
|
function showVariableDetail(variable) {
|
|
const modal = document.getElementById('variable-detail-modal');
|
|
const detailContainer = document.getElementById('variable-detail');
|
|
|
|
let html = `
|
|
<div class="detail-header">
|
|
<h3>${variable.name}</h3>
|
|
${variable.priority_level ? `<span class="priority-badge priority-${variable.priority_level}">Priority ${variable.priority_level}</span>` : ''}
|
|
</div>
|
|
|
|
<div class="detail-section">
|
|
<h4>Description</h4>
|
|
<p>${variable.description || 'No description available'}</p>
|
|
</div>
|
|
|
|
<div class="detail-section">
|
|
<h4>Category</h4>
|
|
<p>${variable.category}</p>
|
|
</div>
|
|
|
|
<div class="detail-section">
|
|
<h4>Statistics</h4>
|
|
<p><strong>Frequency:</strong> ${variable.frequency}</p>
|
|
<p><strong>Coefficient Score:</strong> ${variable.coefficient_score.toFixed(3)}</p>
|
|
<p><strong>Hard Constraint:</strong> ${variable.is_hard_constraint ? 'Yes' : 'No'}</p>
|
|
</div>
|
|
|
|
<div class="detail-section">
|
|
<h4>Principal Assignment</h4>
|
|
<p>${variable.principal_assignment || 'Not specified'}</p>
|
|
</div>
|
|
`;
|
|
|
|
if (variable.mentions && variable.mentions.length > 0) {
|
|
html += `
|
|
<div class="detail-section">
|
|
<h4>Mentions in Document (${variable.mentions.length})</h4>
|
|
<div class="mentions-list">
|
|
${variable.mentions.slice(0, 5).map(mention => `
|
|
<div class="mention-item">
|
|
<div><strong>${mention.section_title || 'Section'}</strong></div>
|
|
<div class="mention-context">${mention.context}</div>
|
|
</div>
|
|
`).join('')}
|
|
${variable.mentions.length > 5 ? `<p style="color: var(--text-secondary);">... and ${variable.mentions.length - 5} more mentions</p>` : ''}
|
|
</div>
|
|
</div>
|
|
`;
|
|
}
|
|
|
|
if (variable.related_variables && variable.related_variables.length > 0) {
|
|
html += `
|
|
<div class="detail-section">
|
|
<h4>Related Variables</h4>
|
|
<ul>
|
|
${variable.related_variables.slice(0, 5).map(rel => `
|
|
<li>${rel.name} (${rel.relationship}, weight: ${rel.weight})</li>
|
|
`).join('')}
|
|
</ul>
|
|
</div>
|
|
`;
|
|
}
|
|
|
|
detailContainer.innerHTML = html;
|
|
modal.style.display = 'block';
|
|
}
|
|
|
|
function initializeOverviewStats() {
|
|
const stats = window.appData.charts?.overview_stats || {};
|
|
const container = document.getElementById('overview-stats');
|
|
|
|
const statsData = [
|
|
{ label: 'Total Variables', value: stats.total_variables || 0 },
|
|
{ label: 'Total Sentences', value: stats.total_sentences || 0 },
|
|
{ label: 'Total Tokens', value: stats.total_tokens || 0 },
|
|
{ label: 'Unique Tokens', value: stats.unique_tokens || 0 }
|
|
];
|
|
|
|
container.innerHTML = statsData.map(stat => `
|
|
<div class="stat-card">
|
|
<div class="value">${stat.value.toLocaleString()}</div>
|
|
<div class="label">${stat.label}</div>
|
|
</div>
|
|
`).join('');
|
|
}
|
|
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
if (window.appData.charts) {
|
|
initializeOverviewStats();
|
|
}
|
|
});
|