Add termination to pdf webworker

Allows to cancel the PDF generation by clicking a cancel-button
This commit is contained in:
Sean Engelhardt 2019-08-27 09:58:30 +02:00
parent e3a7cbf935
commit 64c6327720
5 changed files with 70 additions and 12 deletions

View File

@ -66,6 +66,8 @@ export class PdfDocumentService {
*/
private imageUrls: string[] = [];
private pdfWorker: Worker;
/**
* Constructor
*
@ -396,9 +398,15 @@ export class PdfDocumentService {
* Shows the progress bar earlier
*/
private showProgress(): void {
this.matSnackBar.openFromComponent(ProgressSnackBarComponent, {
const progressBarRef = this.matSnackBar.openFromComponent(ProgressSnackBarComponent, {
duration: 0
});
// Listen to clicks on the cancel button
progressBarRef.onAction().subscribe(() => {
this.cancelPdfCreation();
});
this.progressService.message = this.translate.instant('Creating PDF file ...');
this.progressService.progressMode = 'determinate';
}
@ -459,12 +467,12 @@ export class PdfDocumentService {
const isIE = /msie\s|trident\//i.test(window.navigator.userAgent);
if (typeof Worker !== 'undefined' && !isIE) {
const worker = new Worker('./pdf-worker.worker', {
this.pdfWorker = new Worker('./pdf-worker.worker', {
type: 'module'
});
// the result of the worker
worker.onmessage = ({ data }) => {
this.pdfWorker.onmessage = ({ data }) => {
// if the worker returns a numbers, is always the progress
if (typeof data === 'number') {
// update progress
@ -476,10 +484,11 @@ export class PdfDocumentService {
if (typeof data === 'object') {
this.matSnackBar.dismiss();
saveAs(data, filename, { autoBOM: true });
this.pdfWorker = null;
}
};
worker.postMessage({
this.pdfWorker.postMessage({
doc: JSON.parse(JSON.stringify(doc)),
fonts: fonts,
vfs: vfs
@ -492,6 +501,16 @@ export class PdfDocumentService {
}
}
/**
* Cancel the pdf generation
*/
private cancelPdfCreation(): void {
if (!!this.pdfWorker) {
this.pdfWorker.terminate();
this.pdfWorker = null;
}
}
/**
* Definition of styles for standard papers
*

View File

@ -1,6 +1,18 @@
<div>
{{ message | translate }}
</div>
<div>
<mat-progress-bar [mode]="mode" [value]="value"></mat-progress-bar>
<div class="progress-grid-wrapper">
<div classs="message">
{{ message | translate }}
</div>
<div class="bar">
<mat-progress-bar [mode]="mode" [value]="value"></mat-progress-bar>
</div>
<div class="action">
<button
mat-icon-button
color="warn"
matTooltip="{{ 'Cancel' | translate }}"
(click)="snackBarRef.dismissWithAction()"
>
<mat-icon>close</mat-icon>
</button>
</div>
</div>

View File

@ -0,0 +1,20 @@
.progress-grid-wrapper {
display: grid;
width: 100%;
grid-template-areas:
'message action'
'bar action';
grid-template-columns: auto min-content;
}
.message {
grid-area: message;
}
.bar {
grid-area: bar;
}
.action {
grid-area: action;
}

View File

@ -1,16 +1,18 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { MatSnackBarRef } from '@angular/material';
import { E2EImportsModule } from 'e2e-imports.module';
import { ProgressSnackBarComponent } from './progress-snack-bar.component';
describe('ProgressSnackBarComponent', () => {
fdescribe('ProgressSnackBarComponent', () => {
let component: ProgressSnackBarComponent;
let fixture: ComponentFixture<ProgressSnackBarComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [E2EImportsModule]
imports: [E2EImportsModule],
providers: [{ provide: MatSnackBarRef, useValue: {} }]
}).compileComponents();
}));

View File

@ -6,6 +6,7 @@ import {
OnInit,
ViewEncapsulation
} from '@angular/core';
import { MatSnackBarRef } from '@angular/material';
import { Subscription } from 'rxjs';
import { distinctUntilChanged } from 'rxjs/operators';
@ -78,7 +79,11 @@ export class ProgressSnackBarComponent implements OnInit, OnDestroy {
/**
* Declare the progressService
*/
public constructor(private progressService: ProgressService, private cd: ChangeDetectorRef) {}
public constructor(
private progressService: ProgressService,
private cd: ChangeDetectorRef,
public snackBarRef: MatSnackBarRef<ProgressSnackBarComponent>
) {}
/**
* Get the progress subject and subscribe to the info subject