patron notes UI
authorBill Erickson <berick@esilibrary.com>
Thu, 5 Jun 2014 18:56:43 +0000 (14:56 -0400)
committerBill Erickson <berick@esilibrary.com>
Thu, 5 Jun 2014 18:56:43 +0000 (14:56 -0400)
Signed-off-by: Bill Erickson <berick@esilibrary.com>
Open-ILS/examples/fm_IDL.xml
Open-ILS/src/templates/staff/admin/workstation/t_print_templates.tt2
Open-ILS/src/templates/staff/circ/patron/index.tt2
Open-ILS/src/templates/staff/circ/patron/t_new_note_dialog.tt2 [new file with mode: 0644]
Open-ILS/src/templates/staff/circ/patron/t_noncat_dialog.tt2
Open-ILS/src/templates/staff/circ/patron/t_notes.tt2 [new file with mode: 0644]
Open-ILS/src/templates/staff/share/print_templates/t_patron_note.tt2 [new file with mode: 0644]
Open-ILS/web/js/ui/default/staff/admin/workstation/app.js
Open-ILS/web/js/ui/default/staff/circ/patron/app.js

index 451975f..e4de625 100644 (file)
@@ -2019,7 +2019,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
                        <link field="billing_location" reltype="has_a" key="id" map="" class="aou"/>
                </links>
        </class>
-       <class id="aun" controller="open-ils.cstore" oils_obj:fieldmapper="actor::usr_note" oils_persist:tablename="actor.usr_note" reporter:label="User Note">
+       <class id="aun" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="actor::usr_note" oils_persist:tablename="actor.usr_note" reporter:label="User Note">
                <fields oils_persist:primary="id" oils_persist:sequence="actor.usr_note_id_seq">
                        <field reporter:label="Creation Date/Time" name="create_date" reporter:datatype="timestamp"/>
                        <field reporter:label="Creating Staff" name="creator" reporter:datatype="link"/>
@@ -2033,6 +2033,23 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
                        <link field="usr" reltype="has_a" key="id" map="" class="au"/>
                        <link field="creator" reltype="has_a" key="id" map="" class="au"/>
                </links>
+        <permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
+            <actions>
+                <create permission="UPDATE_USER" context_field="owner">
+                    <context link="usr" field="home_ou"/>
+                </create>
+                               <!-- note: public notes are still accessible via API -->
+                <retrieve permission="UPDATE_USER">
+                    <context link="usr" field="home_ou"/>
+                               </retrieve>
+                <update permission="UPDATE_USER">
+                    <context link="usr" field="home_ou"/>
+                               </update>
+                <delete permission="UPDATE_USER">
+                    <context link="usr" field="home_ou"/>
+                               </delete>
+            </actions>
+        </permacrud>
        </class>
        <class id="aupr" controller="open-ils.cstore" oils_obj:fieldmapper="actor::usr_password_reset" oils_persist:tablename="actor.usr_password_reset" reporter:label="User password reset requests">
                <fields oils_persist:primary="id" oils_persist:sequence="actor.usr_password_reset_id_seq">
index 29d8531..c25c2bd 100644 (file)
@@ -15,6 +15,7 @@
       <option value="bills_current">[% l('Bills, Current') %]</option>
       <option value="bills_historical">[% l('Bills, Historical') %]</option>
       <option value="bill_payment">[% l('Bills, Payment') %]</option>
+      <option value="patron_note">[% l('Patron Note') %]</option>
     </select>
   </div>
   <div class="col-md-7">
index ed33ead..0e638a8 100644 (file)
@@ -91,13 +91,18 @@ angular.module('egCoreMod').run(['egStrings', function(s) {
         </a>
         <ul class="dropdown-menu">
           <li>
-            <a href="./circ/patron/{{patron().id()}}/credentials">
-              [% l('Test Password') %]
+            <a href="./circ/patron/{{patron().id()}}/alerts">
+              [% l('Display Alert and Messages') %]
             </a>
           </li>
           <li>
-            <a href="./circ/patron/{{patron().id()}}/alerts">
-              [% l('Display Alert and Messages') %]
+            <a href="./circ/patron/{{patron().id()}}/notes">
+              [% l('Notes') %]
+            </a>
+          </li>
+          <li>
+            <a href="./circ/patron/{{patron().id()}}/credentials">
+              [% l('Test Password') %]
             </a>
           </li>
        </ul>
diff --git a/Open-ILS/src/templates/staff/circ/patron/t_new_note_dialog.tt2 b/Open-ILS/src/templates/staff/circ/patron/t_new_note_dialog.tt2
new file mode 100644 (file)
index 0000000..cfc5b40
--- /dev/null
@@ -0,0 +1,42 @@
+<form ng-submit="ok(args)" role="form">
+    <div class="modal-header">
+      <button type="button" class="close" ng-click="cancel()" 
+        aria-hidden="true">&times;</button>
+      <h4 class="modal-title">[% l('Create a new note') %]</h4>
+    </div>
+    <div class="modal-body">
+      <div class="form-group row">
+        <div class="col-md-3">
+          <label for="note-title">[% l('Title') %]</label>
+        </div>
+        <div class="col-md-9">
+          <input type="text" class="form-control" focus-me='focusNote' required
+            id="note-title" ng-model="args.title" placeholder="[% l('Title...') %]"/>
+        </div>
+      </div>
+      <div class="form-group row">
+        <div class="col-md-3">
+          <label for="note-pub">[% l('Patron Visible?') %]</label>
+        </div>
+        <div class="col-md-9">
+          <input type="checkbox" class="checkbox" 
+            id="note-pub" ng-model="args.pub"/>
+        </div>
+      </div>
+      <div class="form-group row">
+        <div class="col-md-3">
+          <label for="note-value">[% l('Value') %]</label>
+        </div>
+        <div class="col-md-9">
+          <textarea class="form-control" required
+            id="note-value" ng-model="args.value" placeholder="[% l('Value...') %]">
+          </textarea>
+        </div>
+      </div>
+    </div>
+    <div class="modal-footer">
+      <input type="submit" class="btn btn-primary" value="[% l('OK') %]"/>
+      <button class="btn btn-warning" ng-click="cancel()">[% l('Cancel') %]</button>
+    </div>
+  </div> <!-- modal-content -->
+</form>
index c0c6e53..7cbadfd 100644 (file)
@@ -15,6 +15,7 @@
           <input type="number" class="form-control" focus-me='focusMe' required
             id="noncat-title" ng-model="count" placeholder="[% l('Count...') %]"/>
         </div>
+      </div>
       <div class="modal-footer">
         <input type="submit" class="btn btn-primary" 
             ng-disabled="form.$invalid" value="[% l('OK') %]"/>
diff --git a/Open-ILS/src/templates/staff/circ/patron/t_notes.tt2 b/Open-ILS/src/templates/staff/circ/patron/t_notes.tt2
new file mode 100644 (file)
index 0000000..b83f317
--- /dev/null
@@ -0,0 +1,44 @@
+<div class="row">
+  <div class="col-md-12">
+    <button class="btn btn-default" ng-click="newNote()">
+      [% l('Add New Note') %]
+    </button>
+  </div>
+</div>
+
+<div class="row pad-vert" ng-repeat="note in notes">
+  <div class="col-md-12">
+    <div class="row">
+      <div class="col-md-6 strong-text">{{note.title()}}</div>
+      <div class="col-md-6">
+        <div class="pull-right">
+          <span class="pad-horiz alert alert-warning" ng-if="note.pub() == 't'">[% l('Patron Visible') %]</span>
+          <span class="pad-horiz alert alert-info" ng-if="note.pub() == 'f'">[% l('Staff Only') %]</span>
+          <span class="pad-horiz">{{note.create_date() | date:'short'}}</span>
+          <span>[% l('Created by [_1]', '{{note.creator().usrname()}}') %]</span>
+        </div>
+      </div>
+    </div>
+    <div class="row">
+      <!-- hmm, not sure why the margin-left is needed.. the well? -->
+      <div class="col-md-12 well" style="margin-left:12px">
+        <div class="row">
+          <div class="col-md-8">
+            <div class="">{{note.value()}}</div>
+          </div>
+          <div class="col-md-4">
+            <div class="pull-right">
+              <button ng-click="printNote(note)" class="btn btn-default">
+                [% l('Print') %]
+              </button>
+              <button ng-click="deleteNote(note)" class="btn btn-warning">
+                [% l('Delete') %]
+              </button>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+  <hr/>
+</div>
diff --git a/Open-ILS/src/templates/staff/share/print_templates/t_patron_note.tt2 b/Open-ILS/src/templates/staff/share/print_templates/t_patron_note.tt2
new file mode 100644 (file)
index 0000000..5b98683
--- /dev/null
@@ -0,0 +1,11 @@
+<h3>[% l(
+  'Pertaining to [_1], [_2] [_3] : [_4]',
+  '{{note.usr.family_name}}',
+  '{{note.usr.first_given_name}}',
+  '{{note.usr.second_given_name}}',
+  '{{note.usr.card.barcode}}') %]</h3>
+
+<p>[% l('Created on [_1]', '{{note.create_date | date:"short"}}') %]</p>
+<b>{{note.title}}</b>
+<br/>
+<p>{{note.value}}</p>
index cba0e12..2c52b42 100644 (file)
@@ -305,6 +305,14 @@ function($scope , $q , egCore) {
     // TODO: consider moving the template-specific bits directly
     // into the templates or storing template- specific script files
     // alongside the templates
+    var seed_user = {
+        first_given_name : 'Slow',
+        second_given_name : 'Joe',
+        family_name : 'Jones',
+        card : {
+            barcode : '30393830393'
+        }
+    }
     $scope.preview_scope = {
         current_location : egCore.idl.toHash(
             egCore.org.get(egCore.auth.user().ws_ou())),
@@ -345,6 +353,12 @@ function($scope , $q , egCore) {
         change_given : 0,
         payment_type : 'cash_payment',
         payment_note : 'Here is a payment note',
+        note : {
+            create_date : '2024-12-25T12:01:03',
+            title : 'Test Note Title',
+            usr : seed_user,
+            value : 'This patron is super nice!'
+        }
     }
     $scope.preview_scope.payments = [
         {amount : 1.00, xact : $scope.preview_scope.transactions[0]}, 
index 9dc5e36..ca05dc8 100644 (file)
@@ -130,6 +130,12 @@ angular.module('egPatronApp', ['ngRoute', 'ui.bootstrap',
         resolve : resolver
     });
 
+    $routeProvider.when('/circ/patron/:id/notes', {
+        templateUrl: './circ/patron/t_notes',
+        controller: 'PatronNotesCtrl',
+        resolve : resolver
+    });
+
     $routeProvider.otherwise({redirectTo : '/circ/patron/search'});
 })
 
@@ -833,5 +839,59 @@ function($scope,  $routeParams , $location , egCore , patronSvc) {
 
 }])
 
+.controller('PatronNotesCtrl',
+       ['$scope','$routeParams','$location','egCore','patronSvc','$modal',
+function($scope,  $routeParams , $location , egCore , patronSvc , $modal) {
+    $scope.initTab('other', $routeParams.id);
+    var usr_id = $routeParams.id;
+
+    function refreshPage() {
+        $scope.notes = [];
+        egCore.pcrud.search('aun', 
+            {usr : usr_id}, 
+            {flesh : 1, flesh_fields : {aun : ['creator']}}, 
+            {authoritative : true})
+        .then(null, null, function(note) {
+            $scope.notes.push(note);
+        });
+    }
+
+    $scope.newNote = function() {
+        $modal.open({
+            templateUrl: './circ/patron/t_new_note_dialog',
+            controller: 
+                ['$scope', '$modalInstance',
+            function($scope, $modalInstance) {
+                $scope.focusNote = true;
+                $scope.args = {};
+                $scope.ok = function(count) { $modalInstance.close($scope.args) }
+                $scope.cancel = function () { $modalInstance.dismiss() }
+            }],
+        }).result.then(
+            function(args) {
+                if (!args.value) return;
+                var note = new egCore.idl.aun();
+                note.usr(usr_id);
+                note.title(args.title);
+                note.value(args.value);
+                note.pub(args.pub ? 't' : 'f');
+                note.creator(egCore.auth.user().id());
+                egCore.pcrud.create(note).then(function() {refreshPage()});
+            }
+        );
+    }
+
+    $scope.deleteNote = function(note) {
+        egCore.pcrud.remove(note).then(function() {refreshPage()});
+    }
 
+    $scope.printNote = function(note) {
+        var hash = egCore.idl.toHash(note);
+        hash.usr = egCore.idl.toHash($scope.patron());
+        egCore.hatch.printFromTemplate(
+            'default', 'patron_note', {note : hash});
+    }
+
+    refreshPage();
+}])