--- /dev/null
+<style>
+ /* TODO: move me */
+ .print-template-text {
+ height: 36em;
+ width: 100%;
+ }
+</style>
+
+<h2>[% l('Print Item Labels') %]</h2>
+
+<div class="row">
+ <div class="col-md-5">
+ <div class="form-inline">
+ <div class="form-group">
+ <label for="print_tempate_name">[% l('Template Name') %]</label>
+ <select id="print_template_name" class="form-control" ng-model="print.template_name" ng-change="template_changed()">
+ <option value="item_label">[% l('Item Label') %]</option>
+ </select>
+ <label for="print_context">[% l('Force Printer Context') %]</label>
+ <select class="form-control" ng-model="print.template_context">
+ <option value="default">[% l('Default') %]</option>
+ <option value="receipt">[% l('Receipt') %]</option>
+ <option value="label">[% l('Label') %]</option>
+ <option value="mail">[% l('Mail') %]</option>
+ <option value="offline">[% l('Offline') %]</option>
+ </select>
+ </div>
+ </div>
+ </div>
+ <div class="col-md-7">
+ <button class="btn btn-default pull-left" ng-click="save_locally()">[% l('Save Locally') %]</button>
+ <div class="btn-group pull-right">
+ <span class="btn btn-default btn-file">
+ [% l('Import') %]
+ <input type="file" eg-file-reader container="imported_print_templates.data">
+ </span>
+ <label class="btn btn-default"
+ eg-json-exporter generator="exportable_templates"
+ default-file-name="'[% l('print_templates.json') %]'">
+ [% l('Export Customized Templates') %]
+ </label>
+ </div>
+ </div>
+ <!-- other stuff -->
+</div>
+
+<hr/>
+
+<div class="row">
+ <div class="col-md-5">
+ <h3>[% l('Template') %]</h3>
+ <div ng-if="print.load_failed" class="alert alert-danger">
+ [% l(
+ "Unable to load template '[_1]'. The web server returned an error.",
+ '{{print.template_name}}')
+ %]
+ </div>
+ <div>
+ <textarea ng-model="print.template_content" class="print-template-text">
+ </textarea>
+ </div>
+ </div>
+ <div class="col-md-7">
+ <h3>
+ [% l('Preview') %]
+ <button class="btn btn-default pull-right" ng-click="print_labels()">[% l('Print') %]</button>
+ </h3>
+ <div eg-print-template-output
+ content="print.template_content"
+ context="preview_scope"></div>
+ </div> <!-- col -->
+</div>
+
--- /dev/null
+/**
+ * Vol/Copy Editor
+ */
+
+angular.module('egPrintLabels',
+ ['ngRoute', 'ui.bootstrap', 'egCoreMod', 'egUiMod', 'egGridMod'])
+
+.config(function($routeProvider, $locationProvider, $compileProvider) {
+ $locationProvider.html5Mode(true);
+ $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|blob):/); // grid export
+
+ var resolver = {
+ delay : ['egStartup', function(egStartup) { return egStartup.go(); }]
+ };
+
+ $routeProvider.when('/cat/printlabels/:dataKey', {
+ templateUrl: './cat/printlabels/t_view',
+ controller: 'LabelCtrl',
+ resolve : resolver
+ });
+
+})
+
+.factory('itemSvc',
+ ['egCore',
+function(egCore) {
+
+ var service = {
+ copies : [], // copy barcode search results
+ index : 0 // search grid index
+ };
+
+ service.flesh = {
+ flesh : 3,
+ flesh_fields : {
+ acp : ['call_number','location','status','location','floating','circ_modifier','age_protect'],
+ acn : ['record','prefix','suffix'],
+ bre : ['simple_record','creator','editor']
+ },
+ select : {
+ // avoid fleshing MARC on the bre
+ // note: don't add simple_record.. not sure why
+ bre : ['id','tcn_value','creator','editor'],
+ }
+ }
+
+ // resolved with the last received copy
+ service.fetch = function(barcode, id, noListDupes) {
+ var promise;
+
+ if (barcode) {
+ promise = egCore.pcrud.search('acp',
+ {barcode : barcode, deleted : 'f'}, service.flesh);
+ } else {
+ promise = egCore.pcrud.retrieve('acp', id, service.flesh);
+ }
+
+ var lastRes;
+ return promise.then(
+ function() {return lastRes},
+ null, // error
+
+ // notify reads the stream of copies, one at a time.
+ function(copy) {
+
+ var flatCopy;
+ if (noListDupes) {
+ // use the existing copy if possible
+ flatCopy = service.copies.filter(
+ function(c) {return c.id == copy.id()})[0];
+ }
+
+ if (!flatCopy) {
+ flatCopy = egCore.idl.toHash(copy, true);
+ flatCopy.index = service.index++;
+ service.copies.unshift(flatCopy);
+ }
+
+ return lastRes = {
+ copy : copy,
+ index : flatCopy.index
+ }
+ }
+ );
+ }
+
+ return service;
+}])
+
+/**
+ * Label controller!
+ */
+.controller('LabelCtrl',
+ ['$scope','$q','$window','$routeParams','$location','$timeout','egCore','egNet','ngToast','itemSvc',
+function($scope , $q , $window , $routeParams , $location , $timeout , egCore , egNet , ngToast , itemSvc ) {
+
+ var dataKey = $routeParams.dataKey;
+ console.debug('dataKey: ' + dataKey);
+
+ $scope.print = {
+ template_name : 'item_label',
+ template_output : '',
+ template_context : 'default'
+ };
+
+
+ if (dataKey && dataKey.length > 0) {
+
+ egNet.request(
+ 'open-ils.actor',
+ 'open-ils.actor.anon_cache.get_value',
+ dataKey, 'print-labels-these-copies'
+ ).then(function (data) {
+
+ if (data) {
+
+ console.log(data);
+ $scope.preview_scope = { 'copies' : [] };
+
+ var promises = [];
+
+ angular.forEach(data.copies, function(copy) {
+ promises.push(
+ itemSvc.fetch(null,copy).then(function(res) {
+ $scope.preview_scope.copies.push(egCore.idl.toHash(res.copy, true));
+ })
+ )
+ });
+
+ $q.all(promises).then(function() {
+
+ // today, staff, current_location, etc.
+ egCore.print.fleshPrintScope($scope.preview_scope);
+
+ $scope.template_changed(); // load the default
+
+ })
+ } else {
+ ngToast.danger(egCore.strings.KEY_EXPIRED);
+ }
+
+ });
+ }
+
+ $scope.print_labels = function() {
+ return egCore.print.print({
+ context : $scope.print.template_context,
+ template : $scope.print.template_name,
+ scope : $scope.preview_scope,
+ });
+ }
+
+ $scope.template_changed = function() {
+ $scope.print.load_failed = false;
+ egCore.print.getPrintTemplate($scope.print.template_name)
+ .then(
+ function(html) {
+ $scope.print.template_content = html;
+ console.log('set template content');
+ },
+ function() {
+ $scope.print.template_content = '';
+ $scope.print.load_failed = true;
+ }
+ );
+ egCore.print.getPrintTemplateContext($scope.print.template_name)
+ .then(function(template_context) {
+ $scope.print.template_context = template_context;
+ });
+ }
+
+ $scope.save_locally = function() {
+ egCore.print.storePrintTemplate(
+ $scope.print.template_name,
+ $scope.print.template_content
+ );
+ egCore.print.storePrintTemplateContext(
+ $scope.print.template_name,
+ $scope.print.template_context
+ );
+ }
+
+ $scope.exportable_templates = function() {
+ var templates = {};
+ var contexts = {};
+ var deferred = $q.defer();
+ var promises = [];
+ egCore.hatch.getKeys('eg.print.template').then(function(keys) {
+ angular.forEach(keys, function(key) {
+ if (key.match(/^eg\.print\.template\./)) {
+ promises.push(egCore.hatch.getItem(key).then(function(value) {
+ templates[key.replace('eg.print.template.', '')] = value;
+ }));
+ } else {
+ promises.push(egCore.hatch.getItem(key).then(function(value) {
+ contexts[key.replace('eg.print.template_context.', '')] = value;
+ }));
+ }
+ });
+ $q.all(promises).then(function() {
+ if (Object.keys(templates).length) {
+ deferred.resolve({
+ templates: templates,
+ contexts: contexts
+ });
+ } else {
+ ngToast.warning(egCore.strings.PRINT_TEMPLATES_FAIL_EXPORT);
+ deferred.reject();
+ }
+ });
+ });
+ return deferred.promise;
+ }
+
+ $scope.imported_print_templates = { data : '' };
+ $scope.$watch('imported_print_templates.data', function(newVal, oldVal) {
+ if (newVal && newVal != oldVal) {
+ try {
+ var data = JSON.parse(newVal);
+ angular.forEach(data.templates, function(template_content, template_name) {
+ egCore.print.storePrintTemplate(template_name, template_content);
+ });
+ angular.forEach(data.contexts, function(template_context, template_name) {
+ egCore.print.storePrintTemplateContext(template_name, template_context);
+ });
+ $scope.template_changed(); // refresh
+ ngToast.create(egCore.strings.PRINT_TEMPLATES_SUCCESS_IMPORT);
+ } catch (E) {
+ ngToast.warning(egCore.strings.PRINT_TEMPLATES_FAIL_IMPORT);
+ }
+ }
+ });
+
+}])
+
+//
+.directive('egPrintTemplateOutput', ['$compile',function($compile) {
+ return function(scope, element, attrs) {
+ scope.$watch(
+ function(scope) {
+ return scope.$eval(attrs.content);
+ },
+ function(value) {
+ // create an isolate scope and copy the print context
+ // data into the new scope.
+ // TODO: see also print security concerns in egHatch
+ var result = element.html(value);
+ var context = scope.$eval(attrs.context);
+ var print_scope = scope.$new(true);
+ angular.forEach(context, function(val, key) {
+ print_scope[key] = val;
+ })
+ $compile(element.contents())(print_scope);
+ }
+ );
+ };
+}])
+
+