diff options
| author | Jan-Hendrik Willms <tleilax+studip@gmail.com> | 2025-11-12 14:57:49 +0100 |
|---|---|---|
| committer | Jan-Hendrik Willms <tleilax+studip@gmail.com> | 2025-11-12 14:57:49 +0100 |
| commit | af201feccab8b9a062ceee3b63917b3ba7c3f1f1 (patch) | |
| tree | be761fc7a0c7f4cd0595a36e979e095582a80432 /resources | |
| parent | 5d47c51cae44cc2bc644a9476a35b26bd1687a17 (diff) | |
pdf export for questionnaire may not run in parallel, fixes #5956
Closes #5956
Merge request studip/studip!4552
Diffstat (limited to 'resources')
| -rw-r--r-- | resources/assets/javascripts/lib/questionnaire.js | 37 |
1 files changed, 30 insertions, 7 deletions
diff --git a/resources/assets/javascripts/lib/questionnaire.js b/resources/assets/javascripts/lib/questionnaire.js index 243d26c..7fc5a4c 100644 --- a/resources/assets/javascripts/lib/questionnaire.js +++ b/resources/assets/javascripts/lib/questionnaire.js @@ -226,7 +226,14 @@ const Questionnaire = { } }, - async exportEvaluationAsPDF(results) { + async exportEvaluationAsPDF(results, button = null) { + let initialButtonText = null; + if (button) { + button.setAttribute('disabled', 'disabled'); + initialButtonText = button.innerText; + button.innerText = $gettext('Export läuft...'); + } + const [html2canvas, jsPDF] = await Promise.all([ import('html2canvas').then(m => m.default), import('jspdf').then(m => m.default), @@ -250,10 +257,16 @@ const Questionnaire = { minute: 'numeric' }).format(new Date()); - const questions = results.querySelectorAll('.question'); + const canvasses = []; + // This may seem awkward but since we cannot use parallel processing via + // Promise.all, we need to wait for each render to finish before + // continuing with the next one. + // Since eslint doesn't like await in a loop, we need to use + // Array.reduce(). + await Array.from(results.querySelectorAll('.question')).reduce( + async (prev, element) => { + await prev; - const canvasses = await Promise.all( - Array.from(questions).map(element => { element.querySelectorAll('svg.ct-chart-bar').forEach(svg => { // Remove xmlns attribute from all children of the svg svg.querySelectorAll('[xmlns]').forEach(node => { @@ -267,13 +280,16 @@ const Questionnaire = { svg.style.height = null; }); - return html2canvas(element, { + const canvas = await html2canvas(element, { allowTaint: false, foreignObjectRendering: false, useCORS: true, logging: false - }) - }) + }); + + canvasses.push(canvas); + }, + Promise.resolve() ); //then all renders are finished: @@ -320,6 +336,13 @@ const Questionnaire = { pdf.save(title + '.pdf'); results.classList.remove('print-view'); + + if (button) { + button.removeAttribute('disabled'); + button.innerText = initialButtonText; + } + + return Promise.resolve(); }, addDelayedInit(el, data, isAjax, isMultiple) { |
