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 '@eg/core/hatch.service';
6 import {ToastService} from '@eg/share/toast/toast.service';
7 import {StringService} from '@eg/share/string/string.service';
11 templateUrl: './print.component.html'
14 export class PrintComponent implements OnInit {
16 // Template that requires local processing
17 template: TemplateRef<any>;
19 // Context data used for processing the template.
22 // Insertion point for externally-compiled templates
23 htmlContainer: Element;
27 printQueue: PrintRequest[];
32 private renderer: Renderer2,
33 private elm: ElementRef,
34 private store: StoreService,
35 private serverStore: ServerStoreService,
36 private hatch: HatchService,
37 private toast: ToastService,
38 private strings: StringService,
39 private printer: PrintService) {
40 this.isPrinting = false;
45 this.printer.onPrintRequest$.subscribe(
46 printReq => this.handlePrintRequest(printReq));
49 this.renderer.selectRootElement('#eg-print-html-container');
51 this.serverStore.getItem('eg.hatch.enable.printing')
52 .then(use => this.useHatch = use);
55 handlePrintRequest(printReq: PrintRequest) {
57 if (this.isPrinting) {
58 // Avoid print collisions by queuing requests as needed.
59 this.printQueue.push(printReq);
63 this.isPrinting = true;
65 this.applyTemplate(printReq).then(() => {
66 // Give templates a chance to render before printing
68 this.dispatchPrint(printReq);
74 applyTemplate(printReq: PrintRequest): Promise<any> {
76 if (printReq.template) {
77 // Local Angular template.
78 this.template = printReq.template;
79 this.context = {$implicit: printReq.contextData};
80 return Promise.resolve();
87 promise = Promise.resolve();
89 } else if (printReq.templateName || printReq.templateId) {
90 // Server-compiled template
92 promise = this.printer.compileRemoteTemplate(printReq).then(
94 printReq.text = response.content;
95 printReq.contentType = response.contentType;
99 if (err && err.notFound) {
101 this.strings.interpolate(
102 'eg.print.template.not_found',
103 {name: printReq.templateName}
104 ).then(msg => this.toast.danger(msg));
108 console.error('Print generation failed', printReq);
110 this.strings.interpolate(
111 'eg.print.template.error',
112 {name: printReq.templateName, id: printReq.templateId}
113 ).then(msg => this.toast.danger(msg));
116 return Promise.reject(new Error(
117 'Error compiling server-hosted print template'));
122 console.error('Cannot find template', printReq);
123 return Promise.reject(new Error('Cannot find print template'));
126 return promise.then(() => {
128 // Insert HTML into the browser DOM for in-browser printing.
129 if (printReq.text && !this.useHatch()) {
131 if (printReq.contentType === 'text/plain') {
132 // Wrap text/plain content in pre's to prevent
133 // unintended html formatting.
134 printReq.text = `<pre>${printReq.text}</pre>`;
137 this.htmlContainer.innerHTML = printReq.text;
142 // Clear the print data
144 this.isPrinting = false;
145 this.template = null;
147 this.htmlContainer.innerHTML = '';
149 if (this.printQueue.length) {
150 this.handlePrintRequest(this.printQueue.pop());
154 dispatchPrint(printReq: PrintRequest) {
156 if (!printReq.text) {
157 // Sometimes the results come from an externally-parsed HTML
158 // template, other times they come from an in-page template.
159 printReq.text = this.elm.nativeElement.innerHTML;
162 // Retain a copy of each printed document in localStorage
163 // so it may be reprinted.
164 this.store.setLocalItem('eg.print.last_printed', {
165 content: printReq.text,
166 context: printReq.printContext,
167 content_type: printReq.contentType,
168 show_dialog: printReq.showDialog
172 this.printViaHatch(printReq);
174 // Here the needed HTML is already in the page.
179 printViaHatch(printReq: PrintRequest) {
181 // Send a full HTML document to Hatch
182 let html = printReq.text;
183 if (printReq.contentType === 'text/html') {
184 html = `<html><body>${printReq.text}</body></html>`;
187 this.serverStore.getItem(`eg.print.config.${printReq.printContext}`)
190 const msg = new HatchMessage({
193 settings: config || {},
194 contentType: 'text/html',
195 showDialog: printReq.showDialog
198 this.hatch.sendRequest(msg).then(
199 ok => console.debug('Print request succeeded'),
200 err => console.warn('Print request failed', err)