From d2caea40a5e12e7c81e32dbfd1f946e8971f06d0 Mon Sep 17 00:00:00 2001 From: Bill Erickson Date: Wed, 16 Apr 2014 14:57:47 -0400 Subject: [PATCH] browser staff: more printing and storage Signed-off-by: Bill Erickson --- .../web/js/ui/default/staff/services/printstore.js | 123 ++++++++++++++------- 1 file changed, 83 insertions(+), 40 deletions(-) diff --git a/Open-ILS/web/js/ui/default/staff/services/printstore.js b/Open-ILS/web/js/ui/default/staff/services/printstore.js index 034c39e490..2b2ede6e9c 100644 --- a/Open-ILS/web/js/ui/default/staff/services/printstore.js +++ b/Open-ILS/web/js/ui/default/staff/services/printstore.js @@ -1,11 +1,24 @@ /** - * Core Service - egPrint + * Core Service - egPrintStore + * + * Dispatches print and data storage requests to the appropriate handler. + * + * With each request, if a connection to Hatch is established, the + * request is relayed. If a connection has not been attempted, an + * attempt is made then the request is handled. If Hatch is known to be + * inaccessible, requests are routed to local handlers. + * + * Printing is handled locally with an egPrintContainer whose contents + * are made visible during printing using CSS print media. + * + * Storage requests are handled by $window.localStorage. + * + * Note that all requests return promises, since any request may be + * subject to aschronous processing by Hatch. * */ - angular.module('egCoreMod') - .factory('egPrintStore', ['$q','$window','$timeout', function($q , $window , $timeout) { @@ -17,6 +30,8 @@ angular.module('egCoreMod') service.socket = null; service.hatchAvailable = null; service.hatchURL = 'wss://localhost:8443/hatch'; + service.hatchRequired = false; + // TODO: would be nice to support local fall-through for specific actions // write a message to the Hatch websocket service.sendToHatch = function(msg) { @@ -59,25 +74,18 @@ angular.module('egCoreMod') // it from our tracked requests. service.resolveRequest = function(msg) { - var srcMsg = service.messages[msg.msgid]; - if (!srcMsg) { - console.log( - "egPrintStore found no source message for response " + - msg.msgid - ); - return; - } - - // remove the source message - delete service.messages[msg.msgid]; + // for requests sent through Hatch, only the cached + // request will have the original promise attached + msg.deferred = service.messages[msg.msgid].deferred; + delete service.messages[msg.msgid]; // un-cache // resolve / reject if (msg.success) { console.debug("command succeeded : " + msg.success); - srcMsg.deferred.resolve(msg.success); + msg.deferred.resolve(msg.success); } else { console.error("command failed : " + msg.error); - srcMsg.deferred.reject(msg.error); + msg.deferred.reject(msg.error); } } @@ -85,19 +93,31 @@ angular.module('egCoreMod') service.handleRequestsLocally = function() { service.socket = null; service.hatchAvailable = false; - angular.forEach(service.pending, function(msg) { + + while ( (msg = service.pending.shift()) ) { + + if (service.hatchRequired) { + throw new Error( + "egPrintStore : attempt to perform '" + msg.action + + "' operation failed because no connection to Hatch could be " + + "established and egPrintStore.hatchRequired is set to TRUE" + ); + } + switch(msg.action) { case 'print': - return service.browserPrint(msg); + service.browserPrint(msg); + break; case 'keys': case 'get': case 'set': case 'append': case 'remove': - return service.handleLocalStorageRequest(msg); + service.handleLocalStorageRequest(msg); + break; } service.resolveRequest(msg); - }); + } } service.hatchConnect = function() { @@ -136,6 +156,7 @@ angular.module('egCoreMod') } service.socket.onerror = function() { + if (service.hatchAvailable === false) return; // already registered console.debug( "unable to connect to Hatch server at " + service.hatchURL); service.handleRequestsLocally(); @@ -157,12 +178,15 @@ angular.module('egCoreMod') } } + // print locally via the browser service.browserPrint = function(msg) { // let our local print container handle printing service.onBrowserPrint(msg.contentType, msg.content); msg.success = true; // assume browser print succeeded } + // print the provided content + // supported values for contentType are 'text/html' and 'text/plain' service.print = function(contentType, content) { if (service.hatchAvailable === false) { service.browserPrint(contentType, content); @@ -178,52 +202,71 @@ angular.module('egCoreMod') }); } + // get the value for a stored item service.getItem = function(key) { + return service.dispatchRequest({key : key, action : 'get'}); } + // set the value for a stored or new item service.setItem = function(key, value) { - if (key === null || value === null) { - logger.warn("invalid key or value in egPrintStore.setItem()"); - return $q.reject(); - } - return service.dispatchRequest({ - key : key, - value : value, - action : 'set', - }); + return service.dispatchRequest( + {key : key, value : value, action : 'set'}); + } + + // appends the value to the existing item stored at key. + // If not item is found at key, this behaves just like setItem() + service.appendItem = function(key, value) { + return service.dispatchRequest( + {key : key, value : value, action : 'append'}); } - service.removeItem = function() { + // remove a stored item + service.removeItem = function(key) { + return service.dispatchRequest({key : key, action : 'remove'}); } // if set, prefix limits the return set to keys starting with 'prefix' service.getKeys = function(prefix) { - return service.dispatchRequest({ - key : prefix, - action : 'keys', - }); + return service.dispatchRequest({key : prefix, action : 'keys'}); } // get, set, remove, append, keys : via $window.localStorage service.handleLocalStorageRequest = function(msg) { + console.log('service.handleLocalStorageRequest() ' + msg.action); + var key = msg.key; + var value = msg.value; switch(msg.action) { case 'keys': var keys = []; var idx = 0; - while (true) { - var key = $window.localStorage.keys(idx); - if (key === null) break; - keys.push(key); + while ( (k = $window.localStorage.key(idx++)) !== null) { + // key prefix match test + if (key && k.substr(0, key.length) != key) continue; + keys.push(k); } msg.success = keys; break; case 'set': - $window.localStorage.setItem(msg.key, msg.value); + $window.localStorage.setItem(key, value); msg.success = true; break; - // ... + case 'get': + msg.success = $window.localStorage.getItem(msg.key); + break; + + case 'remove': + $window.localStorage.removeItem(msg.key); + msg.success = true; + break; + + case 'append': + var item = $window.localStorage.getItem(key); + if (item) value = item + value; + $window.localStorage.setItem(key, value); + msg.success = value; + break; } } -- 2.11.0