Angular6 Hatch service WIP
authorBill Erickson <berickxx@gmail.com>
Mon, 17 Sep 2018 15:26:11 +0000 (11:26 -0400)
committerBill Erickson <berickxx@gmail.com>
Mon, 17 Sep 2018 15:26:11 +0000 (11:26 -0400)
Signed-off-by: Bill Erickson <berickxx@gmail.com>
Open-ILS/src/eg2/src/app/common.module.ts
Open-ILS/src/eg2/src/app/share/print/hatch.service.ts [new file with mode: 0644]
Open-ILS/src/eg2/src/app/share/print/print.component.ts

index c83ad39..773cb10 100644 (file)
@@ -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 (file)
index 0000000..2ed9a02
--- /dev/null
@@ -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<HatchMessage> {
+        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);
+        }
+    }
+}
+
index 4f69949..5faf3ef 100644 (file)
@@ -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 = `<html><body>${printReq.text}</body></html>`;
-
-        /*
-        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')
+        );
     }
 }