diff --git a/app.py b/app.py
index 577363b..a7c4d04 100644
--- a/app.py
+++ b/app.py
@@ -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):
diff --git a/templates/time_attendance_records.html b/templates/time_attendance_records.html
index a61f304..22ed1c6 100644
--- a/templates/time_attendance_records.html
+++ b/templates/time_attendance_records.html
@@ -35,10 +35,23 @@
Import Data
{% endif %}
-
+
+
+
+
@@ -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;
+ }
+}
{% endblock %}
\ No newline at end of file