// --- 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} ${combinedDataList.length}`; 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 ? 'Yes' : 'No'; const drawingCell = row.insertCell(); drawingCell.innerHTML = item.found_drawing ? 'Yes' : 'No'; 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} 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 = '
No PDF files found for this project.
'; } } /** * 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 };