-import {Component, OnInit, TemplateRef, ElementRef} from '@angular/core';
-// See dynamic.component for details on why it's commented out.
+import {Component, OnInit, TemplateRef, ElementRef, Renderer2} from '@angular/core';
import {PrintService, PrintRequest} from './print.service';
+import {TemplateParserService} from '@eg/share/util/parser.service';
@Component({
selector: 'eg-print',
export class PrintComponent implements OnInit {
+ // Template that requires local processing
template: TemplateRef<any>;
- //templateString: string;
+
+ // TemplateParserService-compatible template string.
+ templateString: string;
+
+ // Context data used for processing the template.
context: any;
+ htmlContainer: Element;
+
+ // Final HTML print string
+ htmlResult: string;
+
constructor(
+ private renderer: Renderer2,
private elm: ElementRef,
+ private parser: TemplateParserService,
private printer: PrintService
) {}
ngOnInit() {
this.printer.onPrintRequest$.subscribe(
printReq => this.handlePrintRequest(printReq));
+
+ this.htmlContainer =
+ this.renderer.selectRootElement('#eg-print-container');
}
handlePrintRequest(printReq: PrintRequest) {
- this.template = printReq.template;
- //this.templateString = printReq.templateString;
- this.context = {$implicit: printReq.contextData};
+ this.applyTemplate(printReq).then(ok => {
+ // Give templates a chance to render before printing
+ setTimeout(() => this.dispatchPrint(printReq));
+ });
+ }
+
+ applyTemplate(printReq: PrintRequest): Promise<void> {
+ return new Promise((resolve, reject) => {
+
+ if (printReq.template) {
+ // Inline template. Let Angular do the work.
+ this.template = printReq.template;
+ this.context = {$implicit: printReq.contextData};
+ resolve();
+ }
+
+ let promise;
+ if (printReq.templateString) {
+
+ promise = this.parser.apply(
+ printReq.templateString, printReq.contextData);
+
+ } else if (printReq.htmlString) {
+ promise = Promise.resolve(printReq.htmlString);
+ }
- // Give the template a chance to render inline before printing
- setTimeout(() => this.dispatchPrint(printReq));
+ promise.then(html => {
+ this.htmlResult = html;
+
+ if (true /* !this.hatch.isActive */) {
+
+ // Only insert the HTML into the browser DOM when
+ // printing locally
+ this.htmlContainer.innerHTML = this.htmlResult;
+ }
+
+ resolve();
+ });
+ });
}
- dispatchPrint(printReq) {
- /*
- if (this.hatch.isActive) {
- this.printViaHatch();
+ dispatchPrint(printReq: PrintRequest) {
+ if (0 /*this.hatch.isActive*/) {
+ this.printViaHatch(printReq);
} else {
- */
+ // Here the needed HTML is already in the page.
window.print();
- // }
+ }
}
- /*
- printViaHatch(printReq) {
+ printViaHatch(printReq: PrintRequest) {
+
+ if (!this.htmlResult) {
+ // Sometimes the results come from an externally-parsed HTML
+ // template, other times they come from an in-page template.
+ this.htmlResult = this.elm.nativeElement.innerHTML;
+ }
+
+ /*
this.hatch.print({
printContext: printReq.printContext,
- content: this.elm.nativeElement.innerHTML
+ content: this.htmlResult
});
+ */
}
- */
-
}
getContextStringValue(dotpath: string): string {
// Variable replacements may contain filters.
- const pieces = dotpath.split('|');
- const path = pieces[0].trim();
+ const pieces = dotpath.split('|').map(p => p.trim());
+ const path = pieces[0]
const filter = pieces[1];
const data = {
+ datatype: null, // potentially applied below
value: this.getContextValueAt(path)
};
- // Apply some minimal filter handling for now
// TODO: teach the format service about processing due dates.
if (filter) {
- filter = filter.trim();
- if (filter.startsWith('date')) {
- data.datatype = 'timestamp';
- } else if (filter.startsWith('currency')) {
- data.datatype = 'money';
+ const fParts = filter.split(':').map(p => p.trim());
+
+ switch (fParts[0]) {
+ case 'date':
+ data.datatype = 'timestamp';
+ break;
+ case 'currency':
+ data.datatype = 'money';
+ break;
+ case 'limitTo':
+ const size = fParts[1];
+ const offset = fParts[2] || 0;
+ if (size) {
+ data.value =
+ data.value.substring(offset, offset + size);
+ }
+ break;
}
}