264 lines
13 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Multi-Project Progress Monitor</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<link rel="stylesheet" href="/static/css/style.css">
</head>
<body>
<div class="container">
<!-- Project Selector -->
<div class="row mb-3 align-items-center">
<div class="col-auto">
<label for="projectSelector" class="col-form-label">Select Project:</label>
</div>
<div class="col">
<select class="form-select" id="projectSelector">
{% if projects %}
{% for project in projects %}
<option value="{{ project }}">{{ project }}</option>
{% endfor %}
{% else %}
<option value="" disabled>No projects found</option>
{% endif %}
</select>
</div>
<!-- Add Project Button -->
<div class="col-auto">
<button type="button" class="btn btn-success" data-bs-toggle="modal" data-bs-target="#addProjectModal">
Add Project
</button>
</div>
<!-- Manage Files Button -->
<div class="col-auto">
<button type="button" class="btn btn-info" id="manageFilesBtn" data-bs-toggle="modal" data-bs-target="#manageFilesModal" disabled>
Manage Files
</button>
</div>
</div>
<!-- Navigation between views (remains the same) -->
<nav class="nav nav-pills mb-3" id="viewTabs">
<a class="nav-link active" aria-current="page" href="#" data-view="scada">SCADA Progress</a>
<a class="nav-link" href="#" data-view="drawings">Drawing Progress</a>
<a class="nav-link" href="#" data-view="conflicts">Conflicts</a>
</nav>
<!-- Dynamic Content Area -->
<div id="project-content">
<!-- SCADA Content Section -->
<div id="scada-content" class="view-content">
<h1 class="mb-4">SCADA Device Placement Progress (<span class="project-name-display"></span>)</h1>
<p>Compares the Equipment Manifest against the SCADA view.json files.</p>
<div id="overall-scada-progress" class="chart-container">
<span class="chart-label">Overall SCADA Progress</span>
<canvas id="overall-scada-chart-canvas" class="panel-chart-canvas" style="max-width: 200px; max-height: 200px;"></canvas>
<div id="overall-scada-text" style="font-weight: bold; margin-top: 10px;">Found in SCADA: 0/0 (0%)</div>
</div>
<hr>
<h2>SCADA Progress by Control Panel</h2>
<div id="scada-panels-progress">
<p>Loading panel data...</p>
</div>
</div>
<!-- Drawing Content Section (Initially Hidden) -->
<div id="drawings-content" class="view-content" style="display: none;">
<h1 class="mb-4">Drawing Device Placement Progress (<span class="project-name-display"></span>)</h1>
<p>Compares the Equipment Manifest against the extracted text from drawing files (.txt).</p>
<div id="overall-drawing-progress" class="chart-container">
<span class="chart-label">Overall Drawing Progress</span>
<canvas id="overall-drawing-chart-canvas" class="panel-chart-canvas" style="max-width: 200px; max-height: 200px;"></canvas>
<div id="overall-drawing-text" style="font-weight: bold; margin-top: 10px;">Found in Drawing: 0/0 (0%)</div>
</div>
<hr>
<h2>Drawing Progress by Control Panel</h2>
<div id="drawing-panels-progress">
<p>Loading panel data...</p>
</div>
</div>
<!-- Conflicts Content Section (Initially Hidden) -->
<div id="conflicts-content" class="view-content" style="display: none;">
<h1 class="mb-4">SCADA/Drawing Conflicts (<span class="project-name-display"></span>) <span id="conflict-count" class="badge bg-warning ms-2">0</span></h1>
<p>Items found in SCADA views but <strong>not</strong> found in the extracted drawing text files.</p>
<div id="panels-conflicts">
<p>Loading conflict data...</p>
</div>
</div>
</div> <!-- End project-content -->
</div> <!-- End container -->
<!-- Status Bar -->
<div class="status-bar">
Status (<span id="selected-project-status-name">...</span>): <span id="status-message">Initializing...</span> | Last Commit: <span id="last-commit">N/A</span>
</div>
<!-- Bootstrap Modal for Details (remains the same structure, content filled by JS) -->
<div class="modal fade" id="detailsModal" tabindex="-1" aria-labelledby="detailsModalLabel" aria-hidden="true">
<div class="modal-dialog modal-xl">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="detailsModalLabel">Details for Panel: <span></span></h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<table class="table table-sm table-striped">
<thead>
<tr>
<th>Alias</th>
<th>Panel</th>
<th>SCADA Status</th>
<th>Drawing Status</th>
<th>Equipment Type</th>
<th>Type of Conveyor</th>
</tr>
</thead>
<tbody>
<!-- Missing/Found items will be populated here -->
</tbody>
</table>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<!-- NEW: Add Project Modal -->
<div class="modal fade" id="addProjectModal" tabindex="-1" aria-labelledby="addProjectModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="addProjectModalLabel">Add New Project</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form id="addProjectForm" enctype="multipart/form-data">
<div class="mb-3">
<label for="projectName" class="form-label">Project Name</label>
<input type="text" class="form-control" id="projectName" name="projectName" required>
<div class="form-text">Use only letters, numbers, underscores, or hyphens.</div>
</div>
<div class="mb-3">
<label for="repoUrl" class="form-label">Git Repository URL</label>
<input type="url" class="form-control" id="repoUrl" name="repoUrl" required>
<!-- <div class="form-text">The URL will be used for cloning.</div> --> <!-- Commented out as cloning happens immediately -->
</div>
<div class="mb-3">
<label for="manifestFile" class="form-label">Manifest CSV File</label>
<input class="form-control" type="file" id="manifestFile" name="manifestFile" accept=".csv" required>
</div>
<div class="mb-3">
<label for="pdfFiles" class="form-label">Drawing PDF Files</label>
<input class="form-control" type="file" id="pdfFiles" name="pdfFiles" accept=".pdf" multiple required>
</div>
<div id="addProjectStatus" class="mt-3" style="display: none;"></div>
<button type="submit" class="btn btn-primary">Add Project</button>
</form>
</div>
</div>
</div>
</div>
<!-- End Add Project Modal -->
<!-- NEW: Manage Project Files Modal -->
<div class="modal fade" id="manageFilesModal" tabindex="-1" aria-labelledby="manageFilesModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="manageFilesModalLabel">Manage Files for Project: <span class="project-name-display"></span></h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<!-- Existing Files List -->
<h6>Existing Drawing PDFs:</h6>
<div id="existingPdfList" class="list-group mb-3" style="max-height: 200px; overflow-y: auto;">
<!-- Files will be listed here by JS -->
<span class="text-muted">Loading files...</span>
</div>
<hr>
<!-- Upload New Files Form -->
<h6>Upload New PDF Files:</h6>
<form id="uploadPdfsForm" enctype="multipart/form-data">
<div class="mb-3">
<input class="form-control" type="file" id="newPdfFiles" name="pdfFiles" accept=".pdf" multiple required>
<div class="form-text">Select one or more PDF files to add to the project.</div>
</div>
<button type="submit" class="btn btn-success">Upload Selected PDFs</button>
<div id="uploadStatus" class="mt-2" style="display: none;"></div>
</form>
<hr>
<!-- NEW: Upload/Replace Manifest -->
<h6>Update Manifest File:</h6>
<form id="uploadManifestForm" enctype="multipart/form-data">
<div class="mb-3">
<label for="newManifestFile" class="form-label">Select new manifest.csv</label>
<input class="form-control" type="file" id="newManifestFile" name="manifestFile" accept=".csv" required>
<div class="form-text">This will replace the existing manifest for the project.</div>
</div>
<button type="submit" class="btn btn-primary">Update Manifest</button>
<div id="uploadManifestStatus" class="mt-2" style="display: none;"></div>
</form>
<hr>
<!-- Trigger Analysis -->
<h6>Manual Analysis:</h6>
<p class="form-text">After deleting or uploading files, or updating the manifest, you should manually trigger an analysis to update the progress metrics.</p>
<button type="button" id="triggerAnalysisBtn" class="btn btn-warning">Trigger Project Analysis</button>
<div id="analysisTriggerStatus" class="mt-2" style="display: none;"></div>
<hr>
<!-- NEW: Delete Project Section -->
<h6>Delete Project (Warning: Irreversible)</h6>
<p class="form-text text-danger">Deleting the project will remove all associated files (Manifest, PDFs, Extracted Text, Cloned Repo) from the server permanently.</p>
<button type="button" id="deleteProjectBtn" class="btn btn-danger">Delete This Project</button>
<div id="deleteProjectStatus" class="mt-2" style="display: none;"></div>
<hr>
<div id="manageFilesStatus" class="mt-3 alert" style="display: none;"></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<!-- End Manage Project Files Modal -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<!-- Pass initial data to JavaScript -->
<script>
// Render Jinja data into intermediate JS variables
const initialProjectsJson = {{ projects | tojson }};
const initialStatusJson = {{ initial_statuses | tojson }};
// Embed initial data directly into the page for faster initial load
const initialServerData = {
projects: initialProjectsJson,
status: initialStatusJson
// Note: Full progress data is not embedded initially, fetched via SSE
};
</script>
<script src="/static/js/script.js"></script>
</body>
</html>