2025-08-12 13:33:25 +03:00

893 lines
40 KiB
HTML

{% extends 'base.html' %}
{% load static %}
{% block title %}Data Export{% endblock %}
{% block css %}
<link href="{% static 'assets/plugins/select2/dist/css/select2.min.css' %}" rel="stylesheet" />
<link href="{% static 'assets/plugins/daterangepicker/daterangepicker.css' %}" rel="stylesheet" />
{% endblock %}
{% block content %}
<div id="content" class="app-content">
<div class="container">
<ul class="breadcrumb">
<li class="breadcrumb-item"><a href="{% url 'core:dashboard' %}">Dashboard</a></li>
<li class="breadcrumb-item active">Data Export</li>
</ul>
<div class="row align-items-center mb-3">
<div class="col">
<h1 class="page-header">Data Export</h1>
<p class="text-muted">Export system data in various formats</p>
</div>
<div class="col-auto">
<div class="btn-group">
<button type="button" class="btn btn-outline-primary" onclick="showExportHistory()">
<i class="fa fa-history me-2"></i>Export History
</button>
<button type="button" class="btn btn-outline-info" onclick="showScheduledExports()">
<i class="fa fa-clock me-2"></i>Scheduled Exports
</button>
</div>
</div>
</div>
<!-- Export Configuration -->
<div class="row">
<div class="col-md-8">
<div class="card">
<div class="card-header">
<h4 class="card-title">Configure Export</h4>
</div>
<div class="card-body">
<form id="exportForm">
{% csrf_token %}
<!-- Data Source Selection -->
<div class="row mb-4">
<div class="col-md-6">
<label class="form-label">Data Source</label>
<select name="data_source" class="form-select" required>
<option value="">Select data source</option>
<option value="patients">Patients</option>
<option value="appointments">Appointments</option>
<option value="billing">Billing Records</option>
<option value="laboratory">Laboratory Results</option>
<option value="radiology">Radiology Reports</option>
<option value="pharmacy">Pharmacy Records</option>
<option value="inpatients">Inpatient Records</option>
<option value="inventory">Inventory</option>
<option value="hr">HR Records</option>
<option value="users">User Accounts</option>
</select>
</div>
<div class="col-md-6">
<label class="form-label">Export Format</label>
<select name="export_format" class="form-select" required>
<option value="">Select format</option>
<option value="csv">CSV (Comma Separated Values)</option>
<option value="xlsx">Excel (XLSX)</option>
<option value="pdf">PDF Report</option>
<option value="json">JSON</option>
<option value="xml">XML</option>
</select>
</div>
</div>
<!-- Date Range -->
<div class="row mb-4">
<div class="col-md-6">
<label class="form-label">Date Range</label>
<input type="text" name="date_range" class="form-control" placeholder="Select date range">
</div>
<div class="col-md-6">
<label class="form-label">Record Limit</label>
<select name="record_limit" class="form-select">
<option value="">No limit</option>
<option value="100">100 records</option>
<option value="500">500 records</option>
<option value="1000">1,000 records</option>
<option value="5000">5,000 records</option>
<option value="10000">10,000 records</option>
</select>
</div>
</div>
<!-- Field Selection -->
<div class="mb-4">
<label class="form-label">Fields to Export</label>
<div class="row">
<div class="col-md-6">
<div class="form-check">
<input class="form-check-input" type="checkbox" name="select_all_fields" id="selectAllFields">
<label class="form-check-label fw-bold" for="selectAllFields">
Select All Fields
</label>
</div>
<hr>
<div id="availableFields">
<!-- Fields will be populated dynamically -->
</div>
</div>
<div class="col-md-6">
<label class="form-label">Selected Fields</label>
<div id="selectedFields" class="border rounded p-3" style="min-height: 200px;">
<p class="text-muted">Select fields from the left to include in export</p>
</div>
</div>
</div>
</div>
<!-- Filters -->
<div class="mb-4">
<label class="form-label">Filters</label>
<div id="filterContainer">
<div class="filter-group mb-2">
<div class="row">
<div class="col-md-3">
<select name="filter_field[]" class="form-select filter-field">
<option value="">Select field</option>
</select>
</div>
<div class="col-md-2">
<select name="filter_operator[]" class="form-select">
<option value="equals">Equals</option>
<option value="not_equals">Not equals</option>
<option value="contains">Contains</option>
<option value="not_contains">Not contains</option>
<option value="starts_with">Starts with</option>
<option value="ends_with">Ends with</option>
<option value="greater_than">Greater than</option>
<option value="less_than">Less than</option>
<option value="is_null">Is empty</option>
<option value="is_not_null">Is not empty</option>
</select>
</div>
<div class="col-md-5">
<input type="text" name="filter_value[]" class="form-control" placeholder="Filter value">
</div>
<div class="col-md-2">
<button type="button" class="btn btn-outline-danger btn-sm" onclick="removeFilter(this)">
<i class="fa fa-trash"></i>
</button>
</div>
</div>
</div>
</div>
<button type="button" class="btn btn-outline-primary btn-sm" onclick="addFilter()">
<i class="fa fa-plus me-2"></i>Add Filter
</button>
</div>
<!-- Export Options -->
<div class="row mb-4">
<div class="col-md-6">
<label class="form-label">Export Options</label>
<div class="form-check">
<input class="form-check-input" type="checkbox" name="include_headers" checked>
<label class="form-check-label">Include column headers</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" name="include_metadata">
<label class="form-check-label">Include metadata</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" name="compress_file">
<label class="form-check-label">Compress file (ZIP)</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" name="email_export">
<label class="form-check-label">Email export when ready</label>
</div>
</div>
<div class="col-md-6">
<label class="form-label">Sort Options</label>
<div class="row">
<div class="col-md-8">
<select name="sort_field" class="form-select">
<option value="">No sorting</option>
<option value="id">ID</option>
<option value="created_at">Date Created</option>
<option value="updated_at">Date Modified</option>
<option value="name">Name</option>
</select>
</div>
<div class="col-md-4">
<select name="sort_direction" class="form-select">
<option value="asc">Ascending</option>
<option value="desc">Descending</option>
</select>
</div>
</div>
</div>
</div>
<!-- Schedule Options -->
<div class="mb-4">
<div class="form-check">
<input class="form-check-input" type="checkbox" name="schedule_export" id="scheduleExport">
<label class="form-check-label fw-bold" for="scheduleExport">
Schedule this export
</label>
</div>
<div id="scheduleOptions" class="mt-3" style="display: none;">
<div class="row">
<div class="col-md-4">
<label class="form-label">Frequency</label>
<select name="schedule_frequency" class="form-select">
<option value="daily">Daily</option>
<option value="weekly">Weekly</option>
<option value="monthly">Monthly</option>
<option value="quarterly">Quarterly</option>
<option value="yearly">Yearly</option>
</select>
</div>
<div class="col-md-4">
<label class="form-label">Start Date</label>
<input type="date" name="schedule_start_date" class="form-control">
</div>
<div class="col-md-4">
<label class="form-label">Time</label>
<input type="time" name="schedule_time" class="form-control" value="09:00">
</div>
</div>
<div class="row mt-3">
<div class="col-md-12">
<label class="form-label">Email Recipients</label>
<input type="email" name="schedule_recipients" class="form-control"
placeholder="Enter email addresses separated by commas">
</div>
</div>
</div>
</div>
<!-- Action Buttons -->
<div class="d-flex justify-content-between">
<div>
<button type="button" class="btn btn-outline-info" onclick="previewExport()">
<i class="fa fa-eye me-2"></i>Preview
</button>
<button type="button" class="btn btn-outline-warning" onclick="validateExport()">
<i class="fa fa-check me-2"></i>Validate
</button>
</div>
<div>
<button type="button" class="btn btn-secondary" onclick="resetForm()">
<i class="fa fa-times me-2"></i>Reset
</button>
<button type="submit" class="btn btn-primary">
<i class="fa fa-download me-2"></i>Export Data
</button>
</div>
</div>
</form>
</div>
</div>
</div>
<div class="col-md-4">
<!-- Export Summary -->
<div class="card mb-4">
<div class="card-header">
<h5 class="card-title">Export Summary</h5>
</div>
<div class="card-body">
<div class="mb-3">
<label class="text-muted small">Data Source:</label>
<div id="summaryDataSource" class="fw-bold">Not selected</div>
</div>
<div class="mb-3">
<label class="text-muted small">Format:</label>
<div id="summaryFormat" class="fw-bold">Not selected</div>
</div>
<div class="mb-3">
<label class="text-muted small">Estimated Records:</label>
<div id="summaryRecords" class="fw-bold">-</div>
</div>
<div class="mb-3">
<label class="text-muted small">Selected Fields:</label>
<div id="summaryFields" class="fw-bold">0</div>
</div>
<div class="mb-3">
<label class="text-muted small">Filters Applied:</label>
<div id="summaryFilters" class="fw-bold">0</div>
</div>
<div class="mb-3">
<label class="text-muted small">Estimated Size:</label>
<div id="summarySize" class="fw-bold">-</div>
</div>
</div>
</div>
<!-- Quick Export Templates -->
<div class="card">
<div class="card-header">
<h5 class="card-title">Quick Export Templates</h5>
</div>
<div class="card-body">
<div class="d-grid gap-2">
<button type="button" class="btn btn-outline-primary btn-sm" onclick="loadTemplate('patient_list')">
<i class="fa fa-users me-2"></i>Patient List
</button>
<button type="button" class="btn btn-outline-success btn-sm" onclick="loadTemplate('appointment_report')">
<i class="fa fa-calendar me-2"></i>Appointment Report
</button>
<button type="button" class="btn btn-outline-warning btn-sm" onclick="loadTemplate('billing_summary')">
<i class="fa fa-dollar-sign me-2"></i>Billing Summary
</button>
<button type="button" class="btn btn-outline-info btn-sm" onclick="loadTemplate('lab_results')">
<i class="fa fa-flask me-2"></i>Lab Results
</button>
<button type="button" class="btn btn-outline-secondary btn-sm" onclick="loadTemplate('inventory_report')">
<i class="fa fa-boxes me-2"></i>Inventory Report
</button>
</div>
<hr>
<div class="text-center">
<button type="button" class="btn btn-outline-primary btn-sm" onclick="saveAsTemplate()">
<i class="fa fa-save me-2"></i>Save as Template
</button>
</div>
</div>
</div>
</div>
</div>
<!-- Export Progress -->
<div id="exportProgress" class="card mt-4" style="display: none;">
<div class="card-header">
<h4 class="card-title">Export Progress</h4>
</div>
<div class="card-body">
<div class="mb-3">
<div class="d-flex justify-content-between mb-1">
<span>Exporting data...</span>
<span id="progressText">0%</span>
</div>
<div class="progress">
<div id="progressBar" class="progress-bar" role="progressbar" style="width: 0%"></div>
</div>
</div>
<div class="row text-center">
<div class="col-md-4">
<div class="fs-24px fw-600 text-primary" id="exportedCount">0</div>
<div class="text-muted small">Records Exported</div>
</div>
<div class="col-md-4">
<div class="fs-24px fw-600 text-info" id="remainingCount">0</div>
<div class="text-muted small">Remaining</div>
</div>
<div class="col-md-4">
<div class="fs-24px fw-600 text-success" id="fileSizeCount">0 KB</div>
<div class="text-muted small">File Size</div>
</div>
</div>
<div class="mt-3 text-center">
<button type="button" class="btn btn-outline-danger" onclick="cancelExport()">
<i class="fa fa-stop me-2"></i>Cancel Export
</button>
</div>
</div>
</div>
</div>
</div>
<!-- Export History Modal -->
<div class="modal fade" id="exportHistoryModal" tabindex="-1">
<div class="modal-dialog modal-xl">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Export History</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>Date</th>
<th>Data Source</th>
<th>Format</th>
<th>Records</th>
<th>Size</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody id="historyTableBody">
<!-- History will be loaded here -->
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<!-- Preview Modal -->
<div class="modal fade" id="previewModal" tabindex="-1">
<div class="modal-dialog modal-xl">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Export Preview</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div id="previewContent">
<!-- Preview will be loaded here -->
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary" onclick="proceedWithExport()">Proceed with Export</button>
</div>
</div>
</div>
</div>
<!-- Save Template Modal -->
<div class="modal fade" id="saveTemplateModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Save Export Template</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<form id="saveTemplateForm">
<div class="modal-body">
{% csrf_token %}
<div class="mb-3">
<label class="form-label">Template Name</label>
<input type="text" name="template_name" class="form-control" required>
</div>
<div class="mb-3">
<label class="form-label">Description</label>
<textarea name="template_description" class="form-control" rows="3"></textarea>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" name="is_public">
<label class="form-check-label">Make template available to other users</label>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-primary">Save Template</button>
</div>
</form>
</div>
</div>
</div>
{% endblock %}
{% block js %}
<script src="{% static 'assets/plugins/select2/dist/js/select2.min.js' %}"></script>
<script src="{% static 'assets/plugins/moment/moment.min.js' %}"></script>
<script src="{% static 'assets/plugins/daterangepicker/daterangepicker.js' %}"></script>
<script>
var exportId = null;
$(document).ready(function() {
// Initialize date range picker
$('input[name="date_range"]').daterangepicker({
autoUpdateInput: false,
locale: {
cancelLabel: 'Clear'
}
});
$('input[name="date_range"]').on('apply.daterangepicker', function(ev, picker) {
$(this).val(picker.startDate.format('MM/DD/YYYY') + ' - ' + picker.endDate.format('MM/DD/YYYY'));
updateSummary();
});
$('input[name="date_range"]').on('cancel.daterangepicker', function(ev, picker) {
$(this).val('');
updateSummary();
});
// Initialize Select2
$('.form-select').select2();
// Form change handlers
$('select[name="data_source"]').change(function() {
loadAvailableFields();
updateSummary();
});
$('select[name="export_format"]').change(function() {
updateSummary();
});
$('#scheduleExport').change(function() {
$('#scheduleOptions').toggle(this.checked);
});
$('#selectAllFields').change(function() {
$('.field-checkbox').prop('checked', this.checked);
updateSelectedFields();
});
// Form submission
$('#exportForm').submit(function(e) {
e.preventDefault();
startExport();
});
// Save template form
$('#saveTemplateForm').submit(function(e) {
e.preventDefault();
saveTemplate();
});
});
function loadAvailableFields() {
var dataSource = $('select[name="data_source"]').val();
if (!dataSource) return;
$.get('{% url "core:get_export_fields" %}', {data_source: dataSource}, function(data) {
var fieldsHtml = '';
data.fields.forEach(function(field) {
fieldsHtml += '<div class="form-check">' +
'<input class="form-check-input field-checkbox" type="checkbox" name="export_fields" value="' + field.name + '" id="field_' + field.name + '">' +
'<label class="form-check-label" for="field_' + field.name + '">' +
field.label + ' <small class="text-muted">(' + field.type + ')</small>' +
'</label>' +
'</div>';
});
$('#availableFields').html(fieldsHtml);
// Update filter field options
var filterOptions = '<option value="">Select field</option>';
data.fields.forEach(function(field) {
filterOptions += '<option value="' + field.name + '">' + field.label + '</option>';
});
$('.filter-field').html(filterOptions);
// Add change handler for field checkboxes
$('.field-checkbox').change(function() {
updateSelectedFields();
});
});
}
function updateSelectedFields() {
var selectedFields = [];
$('.field-checkbox:checked').each(function() {
var label = $(this).next('label').text();
selectedFields.push(label);
});
if (selectedFields.length > 0) {
var fieldsHtml = '<ul class="list-unstyled">';
selectedFields.forEach(function(field) {
fieldsHtml += '<li><i class="fa fa-check text-success me-2"></i>' + field + '</li>';
});
fieldsHtml += '</ul>';
$('#selectedFields').html(fieldsHtml);
} else {
$('#selectedFields').html('<p class="text-muted">Select fields from the left to include in export</p>');
}
updateSummary();
}
function addFilter() {
var filterHtml = '<div class="filter-group mb-2">' +
'<div class="row">' +
'<div class="col-md-3">' +
'<select name="filter_field[]" class="form-select filter-field">' +
$('.filter-field').first().html() +
'</select>' +
'</div>' +
'<div class="col-md-2">' +
'<select name="filter_operator[]" class="form-select">' +
'<option value="equals">Equals</option>' +
'<option value="not_equals">Not equals</option>' +
'<option value="contains">Contains</option>' +
'<option value="not_contains">Not contains</option>' +
'<option value="starts_with">Starts with</option>' +
'<option value="ends_with">Ends with</option>' +
'<option value="greater_than">Greater than</option>' +
'<option value="less_than">Less than</option>' +
'<option value="is_null">Is empty</option>' +
'<option value="is_not_null">Is not empty</option>' +
'</select>' +
'</div>' +
'<div class="col-md-5">' +
'<input type="text" name="filter_value[]" class="form-control" placeholder="Filter value">' +
'</div>' +
'<div class="col-md-2">' +
'<button type="button" class="btn btn-outline-danger btn-sm" onclick="removeFilter(this)">' +
'<i class="fa fa-trash"></i>' +
'</button>' +
'</div>' +
'</div>' +
'</div>';
$('#filterContainer').append(filterHtml);
updateSummary();
}
function removeFilter(button) {
$(button).closest('.filter-group').remove();
updateSummary();
}
function updateSummary() {
var dataSource = $('select[name="data_source"]').val();
var format = $('select[name="export_format"]').val();
var selectedFieldsCount = $('.field-checkbox:checked').length;
var filtersCount = $('.filter-group').length;
$('#summaryDataSource').text(dataSource ? $('select[name="data_source"] option:selected').text() : 'Not selected');
$('#summaryFormat').text(format ? format.toUpperCase() : 'Not selected');
$('#summaryFields').text(selectedFieldsCount);
$('#summaryFilters').text(filtersCount);
// Estimate record count and file size
if (dataSource && selectedFieldsCount > 0) {
var formData = new FormData($('#exportForm')[0]);
formData.append('estimate_only', 'true');
$.post('{% url "core:estimate_export" %}', formData, function(data) {
$('#summaryRecords').text(data.estimated_records.toLocaleString());
$('#summarySize').text(data.estimated_size);
}).fail(function() {
$('#summaryRecords').text('-');
$('#summarySize').text('-');
});
} else {
$('#summaryRecords').text('-');
$('#summarySize').text('-');
}
}
function previewExport() {
var formData = new FormData($('#exportForm')[0]);
formData.append('preview', 'true');
$.post('{% url "core:preview_export" %}', formData, function(data) {
$('#previewContent').html(data.preview_html);
$('#previewModal').modal('show');
}).fail(function() {
toastr.error('Failed to generate preview');
});
}
function validateExport() {
var formData = new FormData($('#exportForm')[0]);
formData.append('validate', 'true');
$.post('{% url "core:validate_export" %}', formData, function(data) {
if (data.valid) {
toastr.success('Export configuration is valid');
} else {
toastr.error('Validation failed: ' + data.errors.join(', '));
}
}).fail(function() {
toastr.error('Failed to validate export');
});
}
function startExport() {
var formData = new FormData($('#exportForm')[0]);
// Show progress section
$('#exportProgress').show();
// Start export
$.post('{% url "core:start_export" %}', formData, function(data) {
if (data.success) {
exportId = data.export_id;
monitorExport(exportId);
} else {
toastr.error('Failed to start export: ' + data.error);
$('#exportProgress').hide();
}
}).fail(function() {
toastr.error('Failed to start export');
$('#exportProgress').hide();
});
}
function monitorExport(exportId) {
var interval = setInterval(function() {
$.get('{% url "core:get_export_status" %}', {export_id: exportId}, function(data) {
updateExportProgress(data);
if (data.status === 'completed' || data.status === 'failed' || data.status === 'cancelled') {
clearInterval(interval);
showExportResults(data);
}
});
}, 2000);
}
function updateExportProgress(data) {
var percentage = Math.round((data.exported / data.total) * 100);
$('#progressBar').css('width', percentage + '%');
$('#progressText').text(percentage + '%');
$('#exportedCount').text(data.exported.toLocaleString());
$('#remainingCount').text((data.total - data.exported).toLocaleString());
$('#fileSizeCount').text(data.file_size);
}
function showExportResults(data) {
$('#exportProgress').hide();
if (data.status === 'completed') {
toastr.success('Export completed successfully');
// Provide download link
var downloadHtml = '<div class="alert alert-success">' +
'<h5>Export Completed</h5>' +
'<p>Your export has been completed successfully.</p>' +
'<a href="' + data.download_url + '" class="btn btn-primary">' +
'<i class="fa fa-download me-2"></i>Download File' +
'</a>' +
'</div>';
// Show download option
$('<div class="card mt-4"><div class="card-body">' + downloadHtml + '</div></div>').insertAfter('#exportProgress');
} else {
toastr.error('Export failed: ' + data.error);
}
}
function cancelExport() {
if (confirm('Are you sure you want to cancel this export?')) {
$.post('{% url "core:cancel_export" %}', {export_id: exportId}, function(data) {
if (data.success) {
toastr.success('Export cancelled');
$('#exportProgress').hide();
} else {
toastr.error('Failed to cancel export');
}
});
}
}
function loadTemplate(templateName) {
$.get('{% url "core:load_export_template" %}', {template: templateName}, function(data) {
// Populate form with template data
$('select[name="data_source"]').val(data.data_source).trigger('change');
$('select[name="export_format"]').val(data.export_format);
setTimeout(function() {
data.fields.forEach(function(field) {
$('#field_' + field).prop('checked', true);
});
updateSelectedFields();
}, 500);
toastr.success('Template loaded successfully');
}).fail(function() {
toastr.error('Failed to load template');
});
}
function saveAsTemplate() {
$('#saveTemplateModal').modal('show');
}
function saveTemplate() {
var formData = new FormData($('#saveTemplateForm')[0]);
// Add current export configuration
var exportConfig = {
data_source: $('select[name="data_source"]').val(),
export_format: $('select[name="export_format"]').val(),
fields: [],
filters: []
};
$('.field-checkbox:checked').each(function() {
exportConfig.fields.push($(this).val());
});
formData.append('export_config', JSON.stringify(exportConfig));
$.post('{% url "core:save_export_template" %}', formData, function(data) {
if (data.success) {
$('#saveTemplateModal').modal('hide');
toastr.success('Template saved successfully');
} else {
toastr.error('Failed to save template: ' + data.error);
}
}).fail(function() {
toastr.error('Failed to save template');
});
}
function showExportHistory() {
$.get('{% url "core:get_export_history" %}', function(data) {
var tbody = $('#historyTableBody');
tbody.empty();
data.exports.forEach(function(exp) {
var row = '<tr>' +
'<td>' + exp.date + '</td>' +
'<td>' + exp.data_source + '</td>' +
'<td>' + exp.format.toUpperCase() + '</td>' +
'<td>' + exp.record_count.toLocaleString() + '</td>' +
'<td>' + exp.file_size + '</td>' +
'<td><span class="badge bg-' + exp.status_color + '">' + exp.status + '</span></td>' +
'<td>' +
(exp.download_url ? '<a href="' + exp.download_url + '" class="btn btn-outline-primary btn-sm"><i class="fa fa-download"></i></a>' : '') +
'</td>' +
'</tr>';
tbody.append(row);
});
$('#exportHistoryModal').modal('show');
});
}
function showScheduledExports() {
// Implementation for scheduled exports
toastr.info('Scheduled exports feature coming soon');
}
function resetForm() {
$('#exportForm')[0].reset();
$('#selectedFields').html('<p class="text-muted">Select fields from the left to include in export</p>');
$('#availableFields').empty();
$('.filter-group').not(':first').remove();
updateSummary();
}
function proceedWithExport() {
$('#previewModal').modal('hide');
startExport();
}
</script>
<style>
.filter-group {
border: 1px solid #dee2e6;
border-radius: 4px;
padding: 10px;
background-color: #f8f9fa;
}
#selectedFields {
background-color: #f8f9fa;
}
.field-checkbox {
cursor: pointer;
}
.progress {
height: 20px;
}
#exportProgress .card-body {
min-height: 150px;
}
.form-check-label {
cursor: pointer;
}
.export-template-btn {
transition: all 0.3s ease;
}
.export-template-btn:hover {
transform: translateY(-1px);
}
</style>
{% endblock %}