From 719308a83c5fd76e4ff913c33b7ceecabd3c5d5a Mon Sep 17 00:00:00 2001 From: Bill Erickson Date: Mon, 17 Sep 2018 11:26:11 -0400 Subject: [PATCH] Angular6 Hatch service WIP Signed-off-by: Bill Erickson --- Open-ILS/src/eg2/src/app/common.module.ts | 2 + .../src/eg2/src/app/share/print/hatch.service.ts | 109 +++++++++++++++++++++ .../src/eg2/src/app/share/print/print.component.ts | 28 ++++-- 3 files changed, 132 insertions(+), 7 deletions(-) create mode 100644 Open-ILS/src/eg2/src/app/share/print/hatch.service.ts diff --git a/Open-ILS/src/eg2/src/app/common.module.ts b/Open-ILS/src/eg2/src/app/common.module.ts index c83ad392bc..773cb10279 100644 --- a/Open-ILS/src/eg2/src/app/common.module.ts +++ b/Open-ILS/src/eg2/src/app/common.module.ts @@ -14,6 +14,7 @@ They do not have to be added to the providers list. // consider moving these to core... import {FormatService} from '@eg/core/format.service'; +import {HatchService} from '@eg/share/print/hatch.service'; import {PrintService} from '@eg/share/print/print.service'; // Globally available components @@ -62,6 +63,7 @@ export class EgCommonModule { providers: [ DatePipe, CurrencyPipe, + HatchService, PrintService, FormatService ] diff --git a/Open-ILS/src/eg2/src/app/share/print/hatch.service.ts b/Open-ILS/src/eg2/src/app/share/print/hatch.service.ts new file mode 100644 index 0000000000..2ed9a02683 --- /dev/null +++ b/Open-ILS/src/eg2/src/app/share/print/hatch.service.ts @@ -0,0 +1,109 @@ +import {Injectable, EventEmitter} from '@angular/core'; + +export class HatchMessage { + msgid: number; + resolver: (HatchMessage) => void; // promise resolver + rejector: (HatchMessage) => void; // promise rejector + status: number; + message: string; // error message + from: string; + action: string; + settings: any; + content: string; + // Response from Hatch. + response: any; + contentType: string; + showDialog: boolean; + + constructor(hash: any) { + if (hash) { + hash.forEach((val, key) => this[key] = val); + } + } +} + +@Injectable() +export class HatchService { + + isAvailable: boolean; + msgId: number; + messages: {[msgid:number]: HatchMessage}; + + constructor() { + this.isAvailable = null; + this.msgId = 1; + } + + connect() { + + if (this.isAvailable) { + // Already connected + return; + } + + // When the Hatch extension loads, it tacks an attribute onto + // the top-level documentElement to indicate it's available. + if (!window.document.documentElement.getAttribute('hatch-is-open')) { + this.isAvailable = false; + return; + } + + window.addEventListener('message', event => { + + // We only accept messages from our own content script. + if (event.source !== window) { return; } + + // We only care about messages from the Hatch extension. + if (event.data && event.data.from === 'extension') { + + // Avoid logging full Hatch responses. they can get large. + console.debug( + `Hatch responded to message ID ${event.data.msgid}`); + + this.handleResponse(event.data); + } + }); + + this.isAvailable = true; + } + + // Send a request from the browser to Hatch. + sendRequest(msg: HatchMessage): Promise { + if (this.isAvailable === false) { + return Promise.reject('Hatch is not connected'); + } + + msg.msgid = this.msgId++; + msg.from = 'page'; + this.messages[msg.msgid] = msg; + window.postMessage(msg, window.location.origin); + + return new Promise((resolve, reject) => { + msg.resolver = resolve; + msg.rejector = reject; + }); + } + + // Handle the data sent back to the browser from Hatch. + handleResponse(data: any) { + + const msg = this.messages[data.msgid]; + if (!msg) { + console.warn(`No Hatch request found with ID ${data.msgid}`); + return; + } + + delete this.messages[data.msgid]; + msg.response = data.content; + msg.message = data.message; + msg.status = Number(data.status); + + if (msg.status === 200) { + msg.resolver(msg); + } else { + console.error(`Hatch request returned status ${msg.status}`, msg); + msg.rejector(msg); + } + } +} + diff --git a/Open-ILS/src/eg2/src/app/share/print/print.component.ts b/Open-ILS/src/eg2/src/app/share/print/print.component.ts index 4f6994982b..5faf3ef3b4 100644 --- a/Open-ILS/src/eg2/src/app/share/print/print.component.ts +++ b/Open-ILS/src/eg2/src/app/share/print/print.component.ts @@ -1,6 +1,7 @@ import {Component, OnInit, TemplateRef, ElementRef, Renderer2} from '@angular/core'; import {PrintService, PrintRequest} from './print.service'; import {StoreService} from '@eg/core/store.service'; +import {HatchService, HatchMessage} from './hatch.service'; @Component({ selector: 'eg-print', @@ -26,6 +27,7 @@ export class PrintComponent implements OnInit { private renderer: Renderer2, private elm: ElementRef, private store: StoreService, + private hatch: HatchService, private printer: PrintService) { this.isPrinting = false; this.printQueue = []; @@ -37,6 +39,10 @@ export class PrintComponent implements OnInit { this.htmlContainer = this.renderer.selectRootElement('#eg-print-html-container'); + + if (this.store.getLocalItem('eg.hatch.enable.printing')) { + this.hatch.connect(); + } } handlePrintRequest(printReq: PrintRequest) { @@ -109,7 +115,7 @@ export class PrintComponent implements OnInit { show_dialog: printReq.showDialog }); - if (0 /* this.hatch.isActive */) { + if (this.store.getLocalItem('eg.hatch.enable.printing')) { this.printViaHatch(printReq); } else { // Here the needed HTML is already in the page. @@ -121,13 +127,21 @@ export class PrintComponent implements OnInit { // Send a full HTML document to Hatch const html = `${printReq.text}`; - - /* - this.hatch.print({ - printContext: printReq.printContext, - content: html + const config = this.store.getLocalItem( + `eg.print.config.${printReq.printContext}`); + + const msg = new HatchMessage({ + action: 'print', + content : html, + settings : config, + contentType : printReq.contentType, + showDialog : printReq.showDialog }); - */ + + this.hatch.sendRequest(msg).then( + ok => console.debug('Print request succeeded'), + err => console.warn('Print request failed') + ); } } -- 2.11.0