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
writer.writerow([
'ID',
'Employee ID',
'Employee Name',
'Platform',
@@ -7210,17 +7209,12 @@ def export_time_attendance_csv(records, timestamp, filter_str):
'Location Name',
'Action Description',
'Event Description',
'Recorded Address',
'Import Batch ID',
'Import Date',
'Import Source',
'Created Date'
'Recorded Address'
])
# Write data rows
for record in records:
writer.writerow([
record.id,
record.employee_id,
record.employee_name,
record.platform or '',
@@ -7229,11 +7223,7 @@ def export_time_attendance_csv(records, timestamp, filter_str):
record.location_name,
record.action_description,
record.event_description 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 ''
record.recorded_address or ''
])
# Prepare response
@@ -7272,9 +7262,9 @@ def export_time_attendance_excel(records, timestamp, filter_str):
# Headers
headers = [
'ID', 'Employee ID', 'Employee Name', 'Platform', 'Date', 'Time',
'Employee ID', 'Employee Name', 'Platform', 'Date', 'Time',
'Location Name', 'Action Description', 'Event Description',
'Recorded Address', 'Import Batch ID', 'Import Date', 'Import Source'
'Recorded Address'
]
# Write headers
@@ -7289,7 +7279,6 @@ def export_time_attendance_excel(records, timestamp, filter_str):
# Write data
for row_num, record in enumerate(records, 2):
data = [
record.id,
record.employee_id,
record.employee_name,
record.platform or '',
@@ -7298,10 +7287,7 @@ def export_time_attendance_excel(records, timestamp, filter_str):
record.location_name,
record.action_description,
record.event_description 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.recorded_address or ''
]
for col_num, value in enumerate(data, 1):
+142 -6
View File
@@ -35,10 +35,23 @@
Import Data
</a>
{% endif %}
<button class="btn btn-secondary" onclick="exportRecords()">
<i class="fas fa-download"></i>
Export
</button>
<div class="export-dropdown-wrapper">
<button class="btn btn-secondary" onclick="toggleExportMenu(event)">
<i class="fas fa-download"></i>
Export
<i class="fas fa-chevron-down" style="margin-left: 0.5rem; font-size: 0.75rem;"></i>
</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>
@@ -328,10 +341,57 @@ function confirmDelete(recordId, employeeName, date) {
}
}
function exportRecords() {
alert('Export functionality coming soon!');
function toggleExportMenu(event) {
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
document.addEventListener('DOMContentLoaded', function() {
const filterBody = document.getElementById('filterBody');
@@ -430,5 +490,81 @@ document.addEventListener('DOMContentLoaded', function() {
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>
{% endblock %}