|
| 1 | +{% extends 'base.html' %} |
| 2 | +{% load static %} |
| 3 | +{% load crispy_forms_tags %} |
| 4 | + |
| 5 | +{% block extra_css %} |
| 6 | +<style> |
| 7 | + .report-status { |
| 8 | + display: none; |
| 9 | + margin-top: 15px; |
| 10 | + } |
| 11 | + .progress { |
| 12 | + height: 20px; |
| 13 | + margin-bottom: 15px; |
| 14 | + } |
| 15 | +</style> |
| 16 | +{% endblock extra_css %} |
| 17 | + |
| 18 | + |
| 19 | +{% block page_content_title %}Prepare report for {{ readable_report_type }}{% endblock %} |
| 20 | + |
| 21 | +{% block page_content_rows %} |
| 22 | +<!-- Page Content Rows with Card --> |
| 23 | +<div class="row"> |
| 24 | + <div class="col-xl-8 col-lg-8"> |
| 25 | + <div class="card shadow mb-4"> |
| 26 | + |
| 27 | + <!-- Card Header - Dropdown --> |
| 28 | + <div class="card-header py-3 d-flex flex-row align-items-center justify-content-between"> |
| 29 | + <h6 class="m-0 font-weight-bold text-primary">{{ readable_report_type }} Report</h6> |
| 30 | + </div> |
| 31 | + |
| 32 | + <!-- Card Body --> |
| 33 | + <div class="card-body"> |
| 34 | + <form id="reportForm" method="post"> |
| 35 | + <button type="submit" class="btn btn-success">Prepare Report</button> |
| 36 | + </form> |
| 37 | + |
| 38 | + <div id="reportStatus" class="report-status"> |
| 39 | + <div class="progress"> |
| 40 | + <div id="progressBar" class="progress-bar progress-bar-striped progress-bar-animated" |
| 41 | + role="progressbar" style="width: 0%"></div> |
| 42 | + </div> |
| 43 | + <div id="statusMessage" class="alert alert-info"> |
| 44 | + Preparing your report... |
| 45 | + </div> |
| 46 | + </div> |
| 47 | + </div> |
| 48 | + |
| 49 | + |
| 50 | +{% endblock %} |
| 51 | + |
| 52 | + |
| 53 | + |
| 54 | + |
| 55 | +{% block on_dom_load_js %} |
| 56 | + |
| 57 | +let checkInterval; |
| 58 | +let reportUuid = null; |
| 59 | +const accessToken = '{{ access_token }}'; // From context |
| 60 | + |
| 61 | +$('#reportForm').on('submit', function(e) { |
| 62 | + e.preventDefault(); |
| 63 | + |
| 64 | + $('#reportStatus').show(); |
| 65 | + $('#progressBar').css('width', '10%'); |
| 66 | + |
| 67 | + // Disable submit button to prevent multiple requests |
| 68 | + $(this).find('button[type="submit"]').prop('disabled', true); |
| 69 | + |
| 70 | + $.ajax({ |
| 71 | + url: '{{ report_endpoint }}', |
| 72 | + type: 'POST', |
| 73 | + crossDomain: true, |
| 74 | + headers: { |
| 75 | + 'Authorization': `Bearer ${accessToken}` |
| 76 | + }, |
| 77 | + success: function(response) { |
| 78 | + reportUuid = response.uuid; |
| 79 | + $('#progressBar').css('width', '30%'); |
| 80 | + $('#statusMessage').text('Report generation started. Waiting for completion...'); |
| 81 | + |
| 82 | + // Start checking for report completion every 3 seconds |
| 83 | + checkInterval = setInterval(checkReportStatus, 3000); |
| 84 | + }, |
| 85 | + error: function(xhr) { |
| 86 | + alertify.error('Failed to start report generation: ' + (xhr.responseJSON?.detail || xhr.statusText)); |
| 87 | + $('#reportForm button[type="submit"]').prop('disabled', false); |
| 88 | + $('#reportStatus').hide(); |
| 89 | + } |
| 90 | + }); |
| 91 | +}); |
| 92 | + |
| 93 | +function checkReportStatus() { |
| 94 | + if (!reportUuid) return; |
| 95 | + |
| 96 | + // Construct the download URL |
| 97 | + const downloadUrl = '{{ report_result_base_endpoint }}' + reportUuid; |
| 98 | + |
| 99 | + // Try to download the file |
| 100 | + $.ajax({ |
| 101 | + url: downloadUrl, |
| 102 | + type: 'GET', |
| 103 | + crossDomain: true, |
| 104 | + headers: { |
| 105 | + 'Authorization': `Bearer ${accessToken}` |
| 106 | + }, |
| 107 | + xhrFields: { |
| 108 | + responseType: 'blob' // Important for file download |
| 109 | + }, |
| 110 | + success: function(data, status, xhr) { |
| 111 | + const contentType = xhr.getResponseHeader('content-type'); |
| 112 | + if (contentType === 'application/pdf' || contentType === 'application/octet-stream') { |
| 113 | + clearInterval(checkInterval); |
| 114 | + $('#progressBar').css('width', '100%'); |
| 115 | + $('#statusMessage').text('Report ready! Downloading...'); |
| 116 | + |
| 117 | + // Create a download link and trigger click |
| 118 | + const blob = new Blob([data], {type: contentType}); |
| 119 | + const link = document.createElement('a'); |
| 120 | + link.href = window.URL.createObjectURL(blob); |
| 121 | + link.download = '{{ report_type }}_report_' + reportUuid + '.pdf'; |
| 122 | + document.body.appendChild(link); |
| 123 | + link.click(); |
| 124 | + document.body.removeChild(link); |
| 125 | + |
| 126 | + // Reset form after a short delay |
| 127 | + setTimeout(function() { |
| 128 | + $('#reportStatus').hide(); |
| 129 | + $('#reportForm button[type="submit"]').prop('disabled', false); |
| 130 | + $('#progressBar').css('width', '0%'); |
| 131 | + reportUuid = null; |
| 132 | + }, 2000); |
| 133 | + } else { |
| 134 | + // Increment progress bar (but don't go over 90% until download) |
| 135 | + const currentWidth = parseInt($('#progressBar').css('width')); |
| 136 | + if (currentWidth < 90) { |
| 137 | + $('#progressBar').css('width', (currentWidth + 5) + '%'); |
| 138 | + } |
| 139 | + } |
| 140 | + }, |
| 141 | + error: function(xhr) { |
| 142 | + if (xhr.status === 404) { |
| 143 | + // Report not ready yet - this is expected |
| 144 | + const currentWidth = parseInt($('#progressBar').css('width')); |
| 145 | + if (currentWidth < 90) { |
| 146 | + $('#progressBar').css('width', (currentWidth + 2) + '%'); |
| 147 | + } |
| 148 | + } else { |
| 149 | + // Other error - stop checking |
| 150 | + clearInterval(checkInterval); |
| 151 | + alertify.error('Error checking report status: ' + (xhr.responseJSON?.detail || xhr.statusText)); |
| 152 | + $('#reportForm button[type="submit"]').prop('disabled', false); |
| 153 | + } |
| 154 | + } |
| 155 | + }); |
| 156 | +} |
| 157 | +{% endblock on_dom_load_js %} |
| 158 | + |
| 159 | +{% block body_end_extra_scripts %} |
| 160 | + <!-- alertifyjs js --> |
| 161 | + <script src="{% static 'libs/alertifyjs/build/alertify.min.js' %}"></script> |
| 162 | +{% endblock body_end_extra_scripts %} |
0 commit comments