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';
9 templateUrl: './print.component.html'
12 export class PrintComponent implements OnInit {
14 // Template that requires local processing
15 template: TemplateRef<any>;
17 // Context data used for processing the template.
20 // Insertion point for externally-compiled templates
21 htmlContainer: Element;
25 printQueue: PrintRequest[];
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;
39 this.printer.onPrintRequest$.subscribe(
40 printReq => this.handlePrintRequest(printReq));
43 this.renderer.selectRootElement('#eg-print-html-container');
46 handlePrintRequest(printReq: PrintRequest) {
48 if (this.isPrinting) {
49 // Avoid print collisions by queuing requests as needed.
50 this.printQueue.push(printReq);
54 this.isPrinting = true;
56 this.applyTemplate(printReq).then(() => {
57 // Give templates a chance to render before printing
59 this.dispatchPrint(printReq);
65 applyTemplate(printReq: PrintRequest): Promise<any> {
67 if (printReq.template) {
68 // Local Angular template.
69 this.template = printReq.template;
70 this.context = {$implicit: printReq.contextData};
71 return Promise.resolve();
78 promise = Promise.resolve();
80 } else if (printReq.templateName || printReq.templateId) {
81 // Server-compiled template
83 promise = this.printer.compileRemoteTemplate(printReq).then(
85 printReq.text = response.content;
86 printReq.contentType = response.contentType;
89 console.error('Error compiling template', printReq);
90 return Promise.reject(new Error(
91 'Error compiling server-hosted print template'));
96 console.error('Cannot find template', printReq);
97 return Promise.reject(new Error('Cannot find print template'));
100 return promise.then(() => {
102 // Insert HTML into the browser DOM for in-browser printing.
103 if (printReq.text && !this.useHatch()) {
105 if (printReq.contentType === 'text/plain') {
106 // Wrap text/plain content in pre's to prevent
107 // unintended html formatting.
108 printReq.text = `<pre>${printReq.text}</pre>`;
111 this.htmlContainer.innerHTML = printReq.text;
116 // Clear the print data
118 this.isPrinting = false;
119 this.template = null;
121 this.htmlContainer.innerHTML = '';
123 if (this.printQueue.length) {
124 this.handlePrintRequest(this.printQueue.pop());
128 dispatchPrint(printReq: PrintRequest) {
130 if (!printReq.text) {
131 // Sometimes the results come from an externally-parsed HTML
132 // template, other times they come from an in-page template.
133 printReq.text = this.elm.nativeElement.innerHTML;
136 // Retain a copy of each printed document in localStorage
137 // so it may be reprinted.
138 this.store.setLocalItem('eg.print.last_printed', {
139 content: printReq.text,
140 context: printReq.printContext,
141 content_type: printReq.contentType,
142 show_dialog: printReq.showDialog
145 if (this.useHatch()) {
146 this.printViaHatch(printReq);
148 // Here the needed HTML is already in the page.
153 useHatch(): boolean {
154 return this.store.getLocalItem('eg.hatch.enable.printing')
155 && this.hatch.connect();
158 printViaHatch(printReq: PrintRequest) {
160 // Send a full HTML document to Hatch
161 let html = printReq.text;
162 if (printReq.contentType === 'text/html') {
163 html = `<html><body>${printReq.text}</body></html>`;
166 this.serverStore.getItem(`eg.print.config.${printReq.printContext}`)
169 const msg = new HatchMessage({
172 settings: config || {},
173 contentType: 'text/html',
174 showDialog: printReq.showDialog
177 this.hatch.sendRequest(msg).then(
178 ok => console.debug('Print request succeeded'),
179 err => console.warn('Print request failed', err)