MonitorProgress/static/js/modalManager.js

187 lines
8.2 KiB
JavaScript

// --- Modal Management ---
// Store modal instances internally
let detailsModalInstance = null;
let addProjectModalInstance = null;
let manageFilesModalInstance = null;
// Function to initialize Bootstrap modal instances
// Call this once when the DOM is ready
function initializeModals() {
const detailsModalElement = document.getElementById('detailsModal');
if (detailsModalElement) {
detailsModalInstance = new bootstrap.Modal(detailsModalElement);
}
const addProjectModalElement = document.getElementById('addProjectModal');
if (addProjectModalElement) {
addProjectModalInstance = new bootstrap.Modal(addProjectModalElement);
}
const manageFilesModalElement = document.getElementById('manageFilesModal');
if (manageFilesModalElement) {
manageFilesModalInstance = new bootstrap.Modal(manageFilesModalElement);
}
console.log("[ModalManager] Modals initialized.");
}
/**
* Hides a given Bootstrap modal element.
* @param {HTMLElement} modalElement - The DOM element of the modal to hide.
*/
function modalManagerHide(modalElement) {
if (!modalElement) return;
const instance = bootstrap.Modal.getInstance(modalElement);
if (instance) {
instance.hide();
} else {
console.warn("Modal instance not found for element:", modalElement);
}
}
// --- Details Modal ---
/**
* Shows the details modal, populating it with data based on chart click context.
* Relies on global state: currentProjectData, scadaListKeysMap, drawingListKeysMap.
* @param {string} projectName - The name of the selected project.
* @param {string} identifier - '__overall__' or the panel name.
* @param {string} categoryType - 'found' or 'notFound'.
* @param {string} context - 'scada' or 'drawing'.
*/
function modalManagerShowDetails(projectName, identifier, categoryType, context) {
console.log(`[ModalManager] Showing details for: ${projectName} - ${identifier} (${context} / ${categoryType})`);
if (!detailsModalInstance) {
console.error("[ModalManager] Details modal instance not initialized.");
alert("Error: Details modal is not available.");
return;
}
let sourceData = null;
let panelNameDisplay = "";
const listKeysMap = context === 'scada' ? scadaListKeysMap : drawingListKeysMap; // Uses global state
const listTypeLabel = categoryType === 'found'
? (context === 'scada' ? 'Found in SCADA' : 'Found in Drawing')
: (context === 'scada' ? 'Not Found in SCADA' : 'Not Found in Drawing');
// Get the specific project's progress data - uses global state
const projectProgress = (currentProjectData[projectName] && currentProjectData[projectName].progress) ? currentProjectData[projectName].progress : {};
if (identifier === '__overall__') {
sourceData = projectProgress.overall || null;
panelNameDisplay = `Overall (${projectName})`;
} else {
sourceData = (projectProgress.panels) ? projectProgress.panels[identifier] : null;
panelNameDisplay = `${identifier} (${projectName})`;
}
if (!sourceData) {
console.error(`[ModalManager] Could not find source data for modal. Project: ${projectName}, Identifier: ${identifier}, Context: ${context}`);
alert("Error: Could not load details data.");
return;
}
const backendListKeys = listKeysMap[categoryType];
if (!backendListKeys) {
console.error(`[ModalManager] Invalid categoryType: ${categoryType}`);
alert("Error: Invalid data category.");
return;
}
let combinedDataList = [];
backendListKeys.forEach(key => {
if (sourceData[key]) {
combinedDataList = combinedDataList.concat(sourceData[key]);
}
});
// Get modal elements
const modalElement = document.getElementById('detailsModal');
const modalTitleElement = modalElement?.querySelector('.modal-title'); // Use more specific ID if available
const modalTableBody = modalElement?.querySelector('.modal-body tbody');
if (!modalTitleElement || !modalTableBody) {
console.error("[ModalManager] Details modal title or table body element not found.");
alert("Error: Could not display details.");
return;
}
if (combinedDataList.length === 0) {
// Optionally show a message in the modal instead of alert
console.log(`[ModalManager] No items found for ${panelNameDisplay} - ${listTypeLabel}.`);
alert(`No items found for ${panelNameDisplay} - ${listTypeLabel}.`);
return; // Don't show empty modal
}
modalTitleElement.innerHTML = `${listTypeLabel} Items for ${panelNameDisplay} <span class="badge bg-secondary ms-2">${combinedDataList.length}</span>`;
modalTableBody.innerHTML = ''; // Clear previous content
combinedDataList.sort((a, b) => a.alias.localeCompare(b.alias)).forEach(item => {
const row = document.createElement('tr');
row.insertCell().textContent = item.alias;
row.insertCell().textContent = item.control_panel;
const scadaCell = row.insertCell(); scadaCell.innerHTML = item.found_scada ? '<span class="status-yes">Yes</span>' : '<span class="status-no">No</span>';
const drawingCell = row.insertCell(); drawingCell.innerHTML = item.found_drawing ? '<span class="status-yes">Yes</span>' : '<span class="status-no">No</span>';
row.insertCell().textContent = item.equipment_type || 'N/A';
row.insertCell().textContent = item.conveyor_type || 'N/A';
if (item.found_scada && !item.found_drawing) { row.classList.add('table-warning'); }
modalTableBody.appendChild(row);
});
detailsModalInstance.show();
}
// --- Manage Files Modal ---
/**
* Populates the PDF list within the Manage Files modal.
* @param {HTMLElement} pdfListDiv - The container element for the list.
* @param {string} projectName - The name of the current project.
* @param {Array<string>} pdfFiles - An array of PDF filenames.
*/
function modalManagerPopulatePdfList(pdfListDiv, projectName, pdfFiles) {
pdfListDiv.innerHTML = ''; // Clear loading/previous state
if (pdfFiles && pdfFiles.length > 0) {
pdfFiles.forEach(filename => {
const listItem = document.createElement('div');
listItem.className = 'list-group-item d-flex justify-content-between align-items-center';
const nameSpan = document.createElement('span');
nameSpan.textContent = filename;
nameSpan.title = filename; // Show full name on hover
nameSpan.style.overflow = 'hidden';
nameSpan.style.textOverflow = 'ellipsis';
nameSpan.style.whiteSpace = 'nowrap';
nameSpan.style.marginRight = '10px';
const deleteButton = document.createElement('button');
deleteButton.className = 'btn btn-danger btn-sm flex-shrink-0 pdf-delete-btn'; // Add class for event delegation
deleteButton.textContent = 'Delete';
deleteButton.title = `Delete ${filename}`;
deleteButton.dataset.filename = filename; // Store filename in data attribute
deleteButton.dataset.project = projectName; // Store projectname in data attribute
// Remove inline onclick, use event delegation in events.js
// deleteButton.onclick = () => handleDeletePdfClick(projectName, filename);
listItem.appendChild(nameSpan);
listItem.appendChild(deleteButton);
pdfListDiv.appendChild(listItem);
});
} else {
pdfListDiv.innerHTML = '<div class="list-group-item text-muted">No PDF files found for this project.</div>';
}
}
/**
* Updates the title of the Manage Files modal.
* @param {string} projectName - The name of the selected project.
*/
function modalManagerUpdateManageFilesTitle(projectName) {
const manageFilesModalElement = document.getElementById('manageFilesModal');
if (!manageFilesModalElement) return;
manageFilesModalElement.querySelectorAll('.project-name-display').forEach(span => {
span.textContent = projectName || '...'; // Handle null/empty projectName
});
}
// --- Export (if using modules in the future) ---
// export { initializeModals, modalManagerShowDetails, modalManagerPopulatePdfList, modalManagerUpdateManageFilesTitle, modalManagerHide };