LP#1793005 Angular6 Hatch support / printer settings
[working/Evergreen.git] / Open-ILS / src / eg2 / src / app / share / print / print.component.ts
1 import {Component, OnInit, TemplateRef, ElementRef, Renderer2} from '@angular/core';
2 import {PrintService, PrintRequest} from './print.service';
3 import {StoreService} from '@eg/core/store.service';
4 import {ServerStoreService} from '@eg/core/server-store.service';
5 import {HatchService, HatchMessage} from './hatch.service';
6
7 @Component({
8     selector: 'eg-print',
9     templateUrl: './print.component.html'
10 })
11
12 export class PrintComponent implements OnInit {
13
14     // Template that requires local processing
15     template: TemplateRef<any>;
16
17     // Context data used for processing the template.
18     context: any;
19
20     // Insertion point for externally-compiled templates
21     htmlContainer: Element;
22
23     isPrinting: boolean;
24
25     printQueue: PrintRequest[];
26
27     constructor(
28         private renderer: Renderer2,
29         private elm: ElementRef,
30         private store: StoreService,
31         private serverStore: ServerStoreService,
32         private hatch: HatchService,
33         private printer: PrintService) {
34         this.isPrinting = false;
35         this.printQueue = [];
36     }
37
38     ngOnInit() {
39         this.printer.onPrintRequest$.subscribe(
40             printReq => this.handlePrintRequest(printReq));
41
42         this.htmlContainer =
43             this.renderer.selectRootElement('#eg-print-html-container');
44     }
45
46     handlePrintRequest(printReq: PrintRequest) {
47
48         if (this.isPrinting) {
49             // Avoid print collisions by queuing requests as needed.
50             this.printQueue.push(printReq);
51             return;
52         }
53
54         this.isPrinting = true;
55
56         this.applyTemplate(printReq);
57
58         // Give templates a chance to render before printing
59         setTimeout(() => {
60             this.dispatchPrint(printReq);
61             this.reset();
62         });
63     }
64
65     applyTemplate(printReq: PrintRequest) {
66
67         if (printReq.template) {
68             // Inline template.  Let Angular do the interpolationwork.
69             this.template = printReq.template;
70             this.context = {$implicit: printReq.contextData};
71             return;
72         }
73
74         if (printReq.text && !this.useHatch()) {
75             // Insert HTML into the browser DOM for in-browser printing only.
76
77             if (printReq.contentType === 'text/plain') {
78                 // Wrap text/plain content in pre's to prevent
79                 // unintended html formatting.
80                 printReq.text = `<pre>${printReq.text}</pre>`;
81             }
82
83             this.htmlContainer.innerHTML = printReq.text;
84         }
85     }
86
87     // Clear the print data
88     reset() {
89         this.isPrinting = false;
90         this.template = null;
91         this.context = null;
92         this.htmlContainer.innerHTML = '';
93
94         if (this.printQueue.length) {
95             this.handlePrintRequest(this.printQueue.pop());
96         }
97     }
98
99     dispatchPrint(printReq: PrintRequest) {
100
101         if (!printReq.text) {
102             // Sometimes the results come from an externally-parsed HTML
103             // template, other times they come from an in-page template.
104             printReq.text = this.elm.nativeElement.innerHTML;
105         }
106
107         // Retain a copy of each printed document in localStorage
108         // so it may be reprinted.
109         this.store.setLocalItem('eg.print.last_printed', {
110             content: printReq.text,
111             context: printReq.printContext,
112             content_type: printReq.contentType,
113             show_dialog: printReq.showDialog
114         });
115
116         if (this.useHatch()) {
117             this.printViaHatch(printReq);
118         } else {
119             // Here the needed HTML is already in the page.
120             window.print();
121         }
122     }
123
124     useHatch(): boolean {
125         return this.store.getLocalItem('eg.hatch.enable.printing')
126             && this.hatch.connect();
127     }
128
129     printViaHatch(printReq: PrintRequest) {
130
131         // Send a full HTML document to Hatch
132         const html = `<html><body>${printReq.text}</body></html>`;
133
134         this.serverStore.getItem(`eg.print.config.${printReq.printContext}`)
135         .then(config => {
136
137             const msg = new HatchMessage({
138                 action: 'print',
139                 content: html,
140                 settings: config || {},
141                 contentType: 'text/html',
142                 showDialog: printReq.showDialog
143             });
144
145             this.hatch.sendRequest(msg).then(
146                 ok  => console.debug('Print request succeeded'),
147                 err => console.warn('Print request failed', err)
148             );
149         });
150     }
151 }
152