Add stored filename visibility and auto-select functionality to admin upload results
- Added 'Stored Filename' column to Upload Results table showing the actual filename used for storage - Added 'Select All' button for each import type section to quickly select/deselect all files - Improved JavaScript to handle select all/deselect all functionality with proper button state management - Enhanced UI to clearly distinguish between original and stored filenames
This commit is contained in:
@@ -75,6 +75,7 @@
|
|||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Original Filename</th>
|
<th>Original Filename</th>
|
||||||
|
<th>Stored Filename</th>
|
||||||
<th>Import Type</th>
|
<th>Import Type</th>
|
||||||
<th>Size</th>
|
<th>Size</th>
|
||||||
<th>Status</th>
|
<th>Status</th>
|
||||||
@@ -83,7 +84,16 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
{% for result in upload_results %}
|
{% for result in upload_results %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ result.filename }}</td>
|
<td>
|
||||||
|
<strong>{{ result.filename }}</strong>
|
||||||
|
<br>
|
||||||
|
<small class="text-muted">Original name</small>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<code class="small">{{ result.stored_filename }}</code>
|
||||||
|
<br>
|
||||||
|
<small class="text-muted">Stored as</small>
|
||||||
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<span class="badge bg-primary">{{ result.import_type }}</span>
|
<span class="badge bg-primary">{{ result.import_type }}</span>
|
||||||
</td>
|
</td>
|
||||||
@@ -148,12 +158,18 @@
|
|||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<form action="/admin/import/{{ import_type }}" method="post">
|
<form action="/admin/import/{{ import_type }}" method="post">
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label class="form-label">Available Files:</label>
|
<div class="d-flex justify-content-between align-items-center mb-2">
|
||||||
|
<label class="form-label mb-0">Available Files:</label>
|
||||||
|
<button type="button" class="btn btn-outline-primary btn-sm select-all-btn"
|
||||||
|
data-import-type="{{ import_type }}">
|
||||||
|
<i class="bi bi-check-all me-1"></i>Select All
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
<div class="list-group">
|
<div class="list-group">
|
||||||
{% for file in files %}
|
{% for file in files %}
|
||||||
<label class="list-group-item d-flex justify-content-between align-items-center">
|
<label class="list-group-item d-flex justify-content-between align-items-center">
|
||||||
<div>
|
<div>
|
||||||
<input class="form-check-input me-2" type="checkbox"
|
<input class="form-check-input me-2 file-checkbox" type="checkbox"
|
||||||
name="selected_files" value="{{ file.filename }}" id="{{ file.filename }}">
|
name="selected_files" value="{{ file.filename }}" id="{{ file.filename }}">
|
||||||
<small class="text-muted">{{ file.filename }}</small>
|
<small class="text-muted">{{ file.filename }}</small>
|
||||||
<br>
|
<br>
|
||||||
@@ -350,16 +366,54 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
// Start refresh cycle if there are running imports
|
// Start refresh cycle if there are running imports
|
||||||
refreshRunningImports();
|
refreshRunningImports();
|
||||||
|
|
||||||
|
// Select All functionality
|
||||||
|
document.querySelectorAll('.select-all-btn').forEach(button => {
|
||||||
|
button.addEventListener('click', function() {
|
||||||
|
const importType = this.getAttribute('data-import-type');
|
||||||
|
const form = this.closest('form');
|
||||||
|
const checkboxes = form.querySelectorAll('.file-checkbox');
|
||||||
|
const submitBtn = form.querySelector('button[type="submit"]');
|
||||||
|
|
||||||
|
// Toggle all checkboxes in this form
|
||||||
|
const allChecked = Array.from(checkboxes).every(cb => cb.checked);
|
||||||
|
checkboxes.forEach(checkbox => {
|
||||||
|
checkbox.checked = !allChecked;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update button text
|
||||||
|
this.innerHTML = allChecked ?
|
||||||
|
'<i class="bi bi-check-all me-1"></i>Select All' :
|
||||||
|
'<i class="bi bi-dash-square me-1"></i>Deselect All';
|
||||||
|
|
||||||
|
// Update submit button state
|
||||||
|
const hasSelection = Array.from(checkboxes).some(cb => cb.checked);
|
||||||
|
submitBtn.disabled = !hasSelection;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// File selection helpers
|
// File selection helpers
|
||||||
document.querySelectorAll('input[type="checkbox"]').forEach(checkbox => {
|
document.querySelectorAll('.file-checkbox').forEach(checkbox => {
|
||||||
checkbox.addEventListener('change', function() {
|
checkbox.addEventListener('change', function() {
|
||||||
const form = this.closest('form');
|
const form = this.closest('form');
|
||||||
const checkboxes = form.querySelectorAll('input[name="selected_files"]');
|
const checkboxes = form.querySelectorAll('.file-checkbox');
|
||||||
const submitBtn = form.querySelector('button[type="submit"]');
|
const submitBtn = form.querySelector('button[type="submit"]');
|
||||||
|
const selectAllBtn = form.querySelector('.select-all-btn');
|
||||||
|
|
||||||
// Enable/disable submit button based on selection
|
// Enable/disable submit button based on selection
|
||||||
const hasSelection = Array.from(checkboxes).some(cb => cb.checked);
|
const hasSelection = Array.from(checkboxes).some(cb => cb.checked);
|
||||||
submitBtn.disabled = !hasSelection;
|
submitBtn.disabled = !hasSelection;
|
||||||
|
|
||||||
|
// Update select all button state
|
||||||
|
const allChecked = Array.from(checkboxes).every(cb => cb.checked);
|
||||||
|
const noneChecked = Array.from(checkboxes).every(cb => !cb.checked);
|
||||||
|
|
||||||
|
if (allChecked) {
|
||||||
|
selectAllBtn.innerHTML = '<i class="bi bi-dash-square me-1"></i>Deselect All';
|
||||||
|
} else if (noneChecked) {
|
||||||
|
selectAllBtn.innerHTML = '<i class="bi bi-check-all me-1"></i>Select All';
|
||||||
|
} else {
|
||||||
|
selectAllBtn.innerHTML = '<i class="bi bi-check-square me-1"></i>Select All';
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user