Updated export button

This commit is contained in:
2025-10-10 17:32:56 -04:00
parent a8ba9d5c36
commit 04dd3d5d86
2 changed files with 147 additions and 25 deletions
+5 -19
View File
@@ -7201,7 +7201,6 @@ def export_time_attendance_csv(records, timestamp, filter_str):
# Write header # Write header
writer.writerow([ writer.writerow([
'ID',
'Employee ID', 'Employee ID',
'Employee Name', 'Employee Name',
'Platform', 'Platform',
@@ -7210,17 +7209,12 @@ def export_time_attendance_csv(records, timestamp, filter_str):
'Location Name', 'Location Name',
'Action Description', 'Action Description',
'Event Description', 'Event Description',
'Recorded Address', 'Recorded Address'
'Import Batch ID',
'Import Date',
'Import Source',
'Created Date'
]) ])
# Write data rows # Write data rows
for record in records: for record in records:
writer.writerow([ writer.writerow([
record.id,
record.employee_id, record.employee_id,
record.employee_name, record.employee_name,
record.platform or '', record.platform or '',
@@ -7229,11 +7223,7 @@ def export_time_attendance_csv(records, timestamp, filter_str):
record.location_name, record.location_name,
record.action_description, record.action_description,
record.event_description or '', record.event_description or '',
record.recorded_address or '', record.recorded_address or ''
record.import_batch_id or '',
record.import_date.strftime('%Y-%m-%d %H:%M:%S') if record.import_date else '',
record.import_source or '',
record.created_date.strftime('%Y-%m-%d %H:%M:%S') if record.created_date else ''
]) ])
# Prepare response # Prepare response
@@ -7272,9 +7262,9 @@ def export_time_attendance_excel(records, timestamp, filter_str):
# Headers # Headers
headers = [ headers = [
'ID', 'Employee ID', 'Employee Name', 'Platform', 'Date', 'Time', 'Employee ID', 'Employee Name', 'Platform', 'Date', 'Time',
'Location Name', 'Action Description', 'Event Description', 'Location Name', 'Action Description', 'Event Description',
'Recorded Address', 'Import Batch ID', 'Import Date', 'Import Source' 'Recorded Address'
] ]
# Write headers # Write headers
@@ -7289,7 +7279,6 @@ def export_time_attendance_excel(records, timestamp, filter_str):
# Write data # Write data
for row_num, record in enumerate(records, 2): for row_num, record in enumerate(records, 2):
data = [ data = [
record.id,
record.employee_id, record.employee_id,
record.employee_name, record.employee_name,
record.platform or '', record.platform or '',
@@ -7298,10 +7287,7 @@ def export_time_attendance_excel(records, timestamp, filter_str):
record.location_name, record.location_name,
record.action_description, record.action_description,
record.event_description or '', record.event_description or '',
record.recorded_address or '', record.recorded_address or ''
record.import_batch_id or '',
record.import_date.strftime('%Y-%m-%d %H:%M:%S') if record.import_date else '',
record.import_source or ''
] ]
for col_num, value in enumerate(data, 1): for col_num, value in enumerate(data, 1):
+139 -3
View File
@@ -35,10 +35,23 @@
Import Data Import Data
</a> </a>
{% endif %} {% endif %}
<button class="btn btn-secondary" onclick="exportRecords()"> <div class="export-dropdown-wrapper">
<button class="btn btn-secondary" onclick="toggleExportMenu(event)">
<i class="fas fa-download"></i> <i class="fas fa-download"></i>
Export Export
<i class="fas fa-chevron-down" style="margin-left: 0.5rem; font-size: 0.75rem;"></i>
</button> </button>
<div class="export-dropdown-menu" id="exportMenu" style="display: none;">
<button type="button" onclick="exportRecords('excel')" class="export-option">
<i class="fas fa-file-excel" style="color: #10b981;"></i>
<span>Export to Excel</span>
</button>
<button type="button" onclick="exportRecords('csv')" class="export-option">
<i class="fas fa-file-csv" style="color: #3b82f6;"></i>
<span>Export to CSV</span>
</button>
</div>
</div>
</div> </div>
</div> </div>
@@ -328,10 +341,57 @@ function confirmDelete(recordId, employeeName, date) {
} }
} }
function exportRecords() { function toggleExportMenu(event) {
alert('Export functionality coming soon!'); event.stopPropagation();
const menu = document.getElementById('exportMenu');
const isVisible = menu.style.display === 'block';
// Close menu if open, open if closed
menu.style.display = isVisible ? 'none' : 'block';
} }
function exportRecords(format) {
// Close the dropdown menu
document.getElementById('exportMenu').style.display = 'none';
// Get current filter values
const employeeId = document.querySelector('input[name="employee_id"]')?.value || '';
const locationName = document.querySelector('input[name="location_name"]')?.value || '';
const startDate = document.querySelector('input[name="start_date"]')?.value || '';
const endDate = document.querySelector('input[name="end_date"]')?.value || '';
// Build query parameters
const params = new URLSearchParams();
if (employeeId) params.append('employee_id', employeeId);
if (locationName) params.append('location_name', locationName);
if (startDate) params.append('start_date', startDate);
if (endDate) params.append('end_date', endDate);
params.append('format', format);
// Redirect to export endpoint
window.location.href = `/time-attendance/export?${params.toString()}`;
}
// Close dropdown when clicking outside
document.addEventListener('click', function(event) {
const menu = document.getElementById('exportMenu');
const exportWrapper = document.querySelector('.export-dropdown-wrapper');
if (menu && exportWrapper && !exportWrapper.contains(event.target)) {
menu.style.display = 'none';
}
});
// Close dropdown with Escape key
document.addEventListener('keydown', function(event) {
if (event.key === 'Escape') {
const menu = document.getElementById('exportMenu');
if (menu) {
menu.style.display = 'none';
}
}
});
// Initialize filters state // Initialize filters state
document.addEventListener('DOMContentLoaded', function() { document.addEventListener('DOMContentLoaded', function() {
const filterBody = document.getElementById('filterBody'); const filterBody = document.getElementById('filterBody');
@@ -430,5 +490,81 @@ document.addEventListener('DOMContentLoaded', function() {
display: none; display: none;
} }
} }
.export-dropdown-wrapper {
position: relative;
display: inline-block;
}
.export-dropdown-menu {
position: absolute;
top: calc(100% + 0.5rem);
right: 0;
background: #ffffff;
border: 1px solid #e2e8f0;
border-radius: 0.5rem;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
z-index: 1000;
min-width: 200px;
overflow: hidden;
animation: slideDown 0.2s ease-out;
}
@keyframes slideDown {
from {
opacity: 0;
transform: translateY(-10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.export-option {
width: 100%;
padding: 0.875rem 1rem;
border: none;
background: none;
text-align: left;
cursor: pointer;
display: flex;
align-items: center;
gap: 0.75rem;
font-size: 0.9375rem;
color: #0f172a;
transition: background-color 0.15s ease;
border-bottom: 1px solid #f1f5f9;
}
.export-option:last-child {
border-bottom: none;
}
.export-option:hover {
background: #f8fafc;
}
.export-option:active {
background: #f1f5f9;
}
.export-option i {
font-size: 1.125rem;
width: 20px;
text-align: center;
}
.export-option span {
font-weight: 500;
}
/* Responsive adjustments */
@media (max-width: 768px) {
.export-dropdown-menu {
right: auto;
left: 0;
min-width: 180px;
}
}
</style> </style>
{% endblock %} {% endblock %}