209 lines
10 KiB
HTML
209 lines
10 KiB
HTML
{% extends "base.html" %}
|
|
|
|
{% block title %}Home - SCADA vs DWG Manifest Comparison Tool{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="row">
|
|
<div class="col-md-12">
|
|
{% if has_previous_results %}
|
|
<div class="card mb-4">
|
|
<div class="card-header bg-info text-white">
|
|
<h4 class="mb-0">Previous Comparisons</h4>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="row">
|
|
<div class="col-md-8">
|
|
<select id="comparison-selector" class="form-select form-select-lg mb-3">
|
|
<option value="">-- Select a comparison --</option>
|
|
{% for comparison_id, comparison in comparisons.items() %}
|
|
<option value="{{ comparison_id }}">{{ comparison.name }} ({{ comparison.timestamp }})</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="d-grid gap-2">
|
|
<button id="view-comparison-btn" class="btn btn-success" disabled>
|
|
<i class="fas fa-chart-bar"></i> View Selected Comparison
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="comparison-actions" class="row mt-3" style="display: none;">
|
|
<div class="col-md-8">
|
|
<div class="input-group">
|
|
<input type="text" id="comparison-name" class="form-control" placeholder="Rename comparison">
|
|
<button id="rename-comparison-btn" class="btn btn-outline-secondary">
|
|
<i class="fas fa-edit"></i> Rename
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="d-grid gap-2">
|
|
<button id="delete-comparison-btn" class="btn btn-danger">
|
|
<i class="fas fa-trash"></i> Delete Comparison
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<div class="card">
|
|
<div class="card-header bg-primary text-white">
|
|
<h4 class="mb-0">Compare SCADA, DWG, and Manifest Data</h4>
|
|
</div>
|
|
<div class="card-body">
|
|
<p class="lead">Upload your data sources to identify discrepancies between SCADA object metadata, DWG-extracted device list, and mechanical manifest data.</p>
|
|
|
|
<form action="{{ url_for('compare') }}" method="post" enctype="multipart/form-data" class="mb-4">
|
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
|
<div class="mb-3">
|
|
<label for="repo_url" class="form-label">Git Repository URL containing SCADA JSON files</label>
|
|
<input type="url" class="form-control" id="repo_url" name="repo_url" placeholder="http://192.168.5.191:3000/LCI/MTN6.git" required>
|
|
<div class="form-text">Enter the URL of the Git repository containing SCADA object metadata JSON files.</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<label for="manifest_file" class="form-label">Mechanical Manifest Excel File</label>
|
|
<input type="file" class="form-control" id="manifest_file" name="manifest_file" accept=".xlsx" required>
|
|
<div class="form-text">Upload Excel file containing the mechanical manifest data (must include a "Name" column).</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<label for="dwg_file" class="form-label">DWG-Extracted Device List Excel File</label>
|
|
<input type="file" class="form-control" id="dwg_file" name="dwg_file" accept=".xlsx" required>
|
|
<div class="form-text">Upload Excel file containing the DWG-extracted device list (must include a "Name" column).</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="d-grid gap-2">
|
|
<button type="submit" class="btn btn-primary">Compare Data Sources</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
<div class="card-footer">
|
|
<p class="mb-0"><small>Note: All names will be normalized for consistent comparison (uppercase, strip whitespace).</small></p>
|
|
<p class="mb-0 mt-2"><small class="text-muted">Uploaded files and comparison results are shared with all users of this application.</small></p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block extra_js %}
|
|
<script>
|
|
// Store CSRF token for JavaScript use
|
|
const csrfToken = "{{ csrf_token() }}";
|
|
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
const comparisonSelector = document.getElementById('comparison-selector');
|
|
const viewComparisonBtn = document.getElementById('view-comparison-btn');
|
|
const comparisonActions = document.getElementById('comparison-actions');
|
|
const comparisonNameInput = document.getElementById('comparison-name');
|
|
const renameComparisonBtn = document.getElementById('rename-comparison-btn');
|
|
const deleteComparisonBtn = document.getElementById('delete-comparison-btn');
|
|
|
|
if (comparisonSelector) {
|
|
comparisonSelector.addEventListener('change', function() {
|
|
const selectedValue = this.value;
|
|
|
|
if (selectedValue) {
|
|
viewComparisonBtn.disabled = false;
|
|
comparisonActions.style.display = 'flex';
|
|
|
|
// Get the selected option text (comparison name)
|
|
const selectedOption = this.options[this.selectedIndex];
|
|
const comparisonName = selectedOption.text.split(' (')[0];
|
|
comparisonNameInput.value = comparisonName;
|
|
} else {
|
|
viewComparisonBtn.disabled = true;
|
|
comparisonActions.style.display = 'none';
|
|
}
|
|
});
|
|
}
|
|
|
|
if (viewComparisonBtn) {
|
|
viewComparisonBtn.addEventListener('click', function() {
|
|
const selectedValue = comparisonSelector.value;
|
|
if (selectedValue) {
|
|
window.location.href = '/comparison/' + selectedValue;
|
|
}
|
|
});
|
|
}
|
|
|
|
if (renameComparisonBtn) {
|
|
renameComparisonBtn.addEventListener('click', function() {
|
|
const selectedValue = comparisonSelector.value;
|
|
const newName = comparisonNameInput.value.trim();
|
|
|
|
if (selectedValue && newName) {
|
|
fetch('/rename_comparison/' + selectedValue, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
'X-CSRFToken': csrfToken
|
|
},
|
|
body: 'name=' + encodeURIComponent(newName)
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
// Update the option text
|
|
const selectedOption = comparisonSelector.options[comparisonSelector.selectedIndex];
|
|
const timestampPart = selectedOption.text.split(' (')[1];
|
|
selectedOption.text = newName + ' (' + timestampPart;
|
|
|
|
alert('Comparison renamed successfully!');
|
|
} else {
|
|
alert('Failed to rename comparison: ' + data.message);
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Error:', error);
|
|
alert('An error occurred while renaming the comparison.');
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
if (deleteComparisonBtn) {
|
|
deleteComparisonBtn.addEventListener('click', function() {
|
|
const selectedValue = comparisonSelector.value;
|
|
|
|
if (selectedValue && confirm('Are you sure you want to delete this comparison? This action cannot be undone.')) {
|
|
// Use fetch API instead of form submission
|
|
fetch('/delete_comparison/' + selectedValue, {
|
|
method: 'POST',
|
|
headers: {
|
|
'X-CSRFToken': csrfToken
|
|
},
|
|
redirect: 'manual'
|
|
})
|
|
.then(response => {
|
|
if (response.type === 'opaqueredirect') {
|
|
window.location.href = response.url || '/';
|
|
return;
|
|
}
|
|
return response.text();
|
|
})
|
|
.then(html => {
|
|
if (html) {
|
|
window.location.reload();
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Error:', error);
|
|
alert('An error occurred while deleting the comparison. Please try again.');
|
|
});
|
|
}
|
|
});
|
|
}
|
|
});
|
|
</script>
|
|
{% endblock %} |