Simple in-client "activity log" interface (Admin -> Local Administration -> Work...
authorphasefx <phasefx@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Wed, 2 Sep 2009 13:39:27 +0000 (13:39 +0000)
committerphasefx <phasefx@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Wed, 2 Sep 2009 13:39:27 +0000 (13:39 +0000)
The log function itself is part of util/error.js.  Example:

JSAN.use('util.error'); var logger = new util.error();

logger.work_log(

"Staff member Foo circulated item Bar to patron Baz",  // The log message

// Additional Row data to pass to a util.list construct in the work log interface, which can be used in rendering columns, and accessed by actions acting on the list
{
au_id : 1,  // Id for patron Baz; needed if you want the Retrieve Patron action to work with this log entry
acp_barcode : 'Bar', // Barcode of the item; needed if you want the Retrieve Item action to work with this log entry
}
);

TODO:

  * Add logging statements to the Check In interface (complication there is that we don't have patron data, which would be useful) and Patron Registration
  * Possibly add explicit columns for the type of action, the item involved, the patron involved, and the staff involved (to compliment Operator Change), rather than just Message and When.
  * Add filtering support for action types

git-svn-id: svn://svn.open-ils.org/ILS/trunk@13949 dcc99617-32d9-48b4-a31d-7c20da2025e4

13 files changed:
Open-ILS/web/opac/locale/en-US/lang.dtd
Open-ILS/xul/staff_client/chrome/content/OpenILS/global_util.js
Open-ILS/xul/staff_client/chrome/content/main/constants.js
Open-ILS/xul/staff_client/chrome/content/main/menu.js
Open-ILS/xul/staff_client/chrome/content/main/menu_frame_menus.xul
Open-ILS/xul/staff_client/chrome/content/util/error.js
Open-ILS/xul/staff_client/chrome/locale/en-US/offline.properties
Open-ILS/xul/staff_client/server/admin/work_log.js [new file with mode: 0644]
Open-ILS/xul/staff_client/server/admin/work_log.xul [new file with mode: 0644]
Open-ILS/xul/staff_client/server/circ/checkout.js
Open-ILS/xul/staff_client/server/circ/util.js
Open-ILS/xul/staff_client/server/locale/en-US/circ.properties
Open-ILS/xul/staff_client/server/patron/display.js

index a8a2045..3648812 100644 (file)
 <!ENTITY staff.admin.survey.save_question.label "Save this Question">
 <!ENTITY staff.admin.survey.staff_client.label "Staff Client:">
 <!ENTITY staff.admin.survey.start.label "Start:">
+<!ENTITY staff.admin.work_log.list1.header "Most Recent Staff Actions">
+<!ENTITY staff.admin.work_log.list2.header "Most Recently Affected Patrons and Last Action for each">
+<!ENTITY staff.admin.work_log.refresh_btn.label "Refresh">
+<!ENTITY staff.admin.work_log.refresh_btn.accesskey "R">
+<!ENTITY staff.admin.work_log.list1.retrieve_item_btn.label "Retrieve Item">
+<!ENTITY staff.admin.work_log.list1.retrieve_item_btn.accesskey "I">
+<!ENTITY staff.admin.work_log.list1.retrieve_patron_btn.label "Retrieve Patron">
+<!ENTITY staff.admin.work_log.list1.retrieve_patron_btn.accesskey "P">
+<!ENTITY staff.admin.work_log.list2.retrieve_patron_btn.label "Retrieve Patron">
+<!ENTITY staff.admin.work_log.list2.retrieve_patron_btn.accesskey "n">
 <!ENTITY staff.auth.login_header "Log in">
 <!ENTITY staff.auth.logoff_prompt "Log off">
 <!ENTITY staff.auth.logoff_prompt.accesskey "f">
 <!ENTITY staff.main.menu.admin.local_admin.conify.grp_penalty_threshold.label "Group Penalty Thresholds">
 <!ENTITY staff.main.menu.admin.local_admin.circ_matrix_matchpoint.label "Circulation Policies">
 <!ENTITY staff.main.menu.admin.local_admin.hold_matrix_matchpoint.label "Hold Policies">
+<!ENTITY staff.main.menu.admin.local_admin.work_log.label "Work Log">
+<!ENTITY staff.main.menu.admin.local_admin.work_log.accesskey "W">
 
 <!ENTITY staff.main.menu.admin.server_admin.label "Server Administration">
 <!ENTITY staff.main.menu.admin.server_admin.conify.org_unit_type.label "Organization Types">
index f3cbb4d..4cc9467 100644 (file)
@@ -3,6 +3,8 @@
        function ses(a) {
                JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
                switch(a) {
+            case 'staff_id' : return data.list.au[0].id(); break;
+            case 'staff_usrname' : return data.list.au[0].usrname(); break;
             case 'ws_ou' :
                 return data.list.au[0].ws_ou();
             break;
index c2b6a1b..6043e55 100644 (file)
@@ -349,6 +349,7 @@ const urls = {
        'XUL_VOLUME_BUCKETS' : '/xul/server/cat/volume_buckets.xul',
        'XUL_VOLUME_COPY_CREATOR' : '/xul/server/cat/volume_copy_creator.xul',
        'XUL_VOLUME_EDITOR' : '/xul/server/cat/volume_editor.xul',
+    'XUL_WORK_LOG' : '/xul/server/admin/work_log.xul',
        'XUL_Z3950_IMPORT' : '/xul/server/cat/z3950.xul',
        'TEST_HTML' : '/xul/server/main/test.html',
        'TEST_XUL' : '/xul/server/main/test.xul',
index 838f8af..c8e3293 100644 (file)
@@ -95,7 +95,7 @@ main.menu.prototype = {
             obj.set_tab( 
                 loc, 
                 {'tab_name' : label, 'browser' : false }, 
-                {'no_xulG' : false, 'show_print_button' : false, show_nav_buttons:true
+                {'no_xulG' : false, 'show_print_button' : false, 'show_nav_buttons' : true 
             );
         }
 
@@ -553,6 +553,16 @@ main.menu.prototype = {
                 function() { open_eg_web_page('conify/global/config/hold_matrix_matchpoint', 
                     'menu.local_admin.hold_matrix_matchpoint.tab'); }
             ],
+            'cmd_local_admin_work_log' : [
+                ['oncommand'],
+                function() { 
+                    obj.set_tab(
+                        urls.XUL_WORK_LOG,
+                        { 'tab_name' : offlineStrings.getString('menu.local_admin.work_log.tab') },
+                        {}
+                    );
+                }
+            ],
             'cmd_server_admin_org_type' : [
                 ['oncommand'],
                 function() { open_conify_page('actor/org_unit_type', null); }
index f32be81..0599c16 100644 (file)
     <command id="cmd_local_admin_transit_list"/>
     <command id="cmd_local_admin_circ_matrix_matchpoint"/>
     <command id="cmd_local_admin_hold_matrix_matchpoint"/>
+    <command id="cmd_local_admin_work_log"/>
 
     <!-- server admin menu commands -->
     <command id="cmd_server_admin_org_type"/>
                 <menuitem label="&staff.server.admin.index.transit_list;" command="cmd_local_admin_transit_list"/>
                 <menuitem label="&staff.main.menu.admin.local_admin.circ_matrix_matchpoint.label;" command="cmd_local_admin_circ_matrix_matchpoint"/>
                 <menuitem label="&staff.main.menu.admin.local_admin.hold_matrix_matchpoint.label;" command="cmd_local_admin_hold_matrix_matchpoint"/>
+                <menuitem label="&staff.main.menu.admin.local_admin.work_log.label;" accesskey="&staff.main.menu.admin.local_admin.work_log.accesskey;" command="cmd_local_admin_work_log"/>
             </menupopup>
         </menu>
                <menu id="main.menu.admin.server" label="&staff.main.menu.admin.server_admin.label;">
index bf0acad..758b155 100644 (file)
@@ -552,7 +552,55 @@ util.error.prototype = {
                        return false; // We can pass over low surrogates now as the second component in a pair which we have already processed  
                }  
                return str[i];  
-       }  
+       },
+
+    'work_log' : function(msg,row_data) {
+        try {
+            JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.stash_retrieve();
+            var max_entries = data.hash.aous['ui.admin.work_log.max_entries'] || 20;
+            if (! data.work_log) data.work_log = [];
+            if (! row_data) row_data = {};
+            row_data.message = msg;
+            row_data.when = new Date();
+            var ds = { 
+                retrieve_id: js2JSON( { 'au_id' : row_data.au_id, 'au_barcode' : row_data.au_barcode, 'au_family_name' : row_data.au_family_name, 'acp_id' : row_data.acp_id, 'acp_barcode' : row_data.acp_barcode } ), 
+                row: { my: row_data },
+                to_top: true
+            };
+            data.work_log.push( ds );
+            if (data.work_log.length > max_entries) data.work_log.shift();
+            data.stash('work_log');
+            if (row_data.au_id) {
+               this.patron_log(msg,row_data); 
+            }
+        } catch(E) {
+            try { this.standard_unexpected_error_alert('error in error.js, work_log(): ',E); } catch(F) { alert(E); }
+        }
+    },
+
+    'patron_log' : function(msg,row_data) {
+        try {
+            JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.stash_retrieve();
+            var max_entries = data.hash.aous['ui.admin.patron_log.max_entries'] || 10;
+            if (! data.patron_log) data.patron_log = [];
+            if (! row_data) row_data = {};
+            row_data.message = msg;
+            row_data.when = new Date();
+            var ds = { 
+                retrieve_id: js2JSON( { 'au_id' : row_data.au_id, 'au_barcode' : row_data.au_barcode, 'au_family_name' : row_data.au_family_name, 'acp_id' : row_data.acp_id, 'acp_barcode' : row_data.acp_barcode } ), 
+                row: { my: row_data },
+                to_top: true
+            };
+            if (data.patron_log.length > 0) {
+                if ( data.patron_log[ data.patron_log.length -1 ].row.my.au_id == row_data.au_id ) data.patron_log.pop();
+            }
+            data.patron_log.push( ds );
+            if (data.patron_log.length > max_entries) data.patron_log.shift();
+            data.stash('patron_log');
+        } catch(E) {
+            try { this.standard_unexpected_error_alert('error in error.js, patron_log(): ',E); } catch(F) { alert(E); }
+        }
+    } 
 }
 
 dump('exiting util/error.js\n');
index de91b62..086d85c 100644 (file)
@@ -227,3 +227,4 @@ menu.cmd_acq_view_exchange_rate.tab=Exchange Rates
 menu.cmd_acq_view_distrib_formula.tab=Distribution Formulas
 menu.local_admin.circ_matrix_matchpoint.tab=Circulation Policies
 menu.local_admin.hold_matrix_matchpoint.tab=Hold Policies
+menu.local_admin.work_log.tab=Work Log
diff --git a/Open-ILS/xul/staff_client/server/admin/work_log.js b/Open-ILS/xul/staff_client/server/admin/work_log.js
new file mode 100644 (file)
index 0000000..8ae47c1
--- /dev/null
@@ -0,0 +1,161 @@
+var error;
+var list1; var selected1 = [];
+var list2; var selected2 = [];
+var data;
+
+function my_init() {
+    try {
+        netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+        if (typeof JSAN == 'undefined') { throw( "The JSAN library object is missing."); }
+        JSAN.errorLevel = "die"; // none, warn, or die
+        JSAN.addRepository('/xul/server/');
+        JSAN.use('util.error'); error = new util.error();
+        error.sdump('D_TRACE','my_init() for main_test.xul');
+
+        JSAN.use('OpenILS.data'); data = new OpenILS.data(); data.stash_retrieve();
+
+        init_lists();
+        set_behavior();
+        populate_lists();
+        default_focus();
+
+    } catch(E) {
+        try { error.standard_unexpected_error_alert('admin/work_log.xul,my_init():',E); } catch(F) { alert(E); }
+    }
+}
+
+function default_focus() {
+    var btn = document.getElementById('refresh_btn');
+    if (btn) btn.focus();
+}
+
+function init_lists() {
+    try {
+        var cmd_retrieve_item = document.getElementById('cmd_retrieve_item');
+        var cmd_retrieve_patron1 = document.getElementById('cmd_retrieve_patron1');
+        var cmd_retrieve_patron2 = document.getElementById('cmd_retrieve_patron2');
+
+        JSAN.use('util.list');
+
+        list1 = new util.list('work_action_log');
+        list2 = new util.list('work_patron_log');
+
+        JSAN.use('circ.util'); var columns = circ.util.work_log_columns({}); var column_mapper_func = circ.util.std_map_row_to_columns();
+
+        list1.init( {
+            'columns' : columns,
+            'map_row_to_columns' : column_mapper_func,
+            'on_select' : function(ev) {
+                JSAN.use('util.functional'); var sel = list1.retrieve_selection();
+                selected1 = util.functional.map_list( sel, function(o) { return JSON2js(o.getAttribute('retrieve_id')); });
+                if (selected1.length == 0) { 
+                    cmd_retrieve_patron1.setAttribute('disabled','true');
+                    cmd_retrieve_item.setAttribute('disabled','true');
+                } else { 
+                    cmd_retrieve_patron1.setAttribute('disabled','false');
+                    cmd_retrieve_item.setAttribute('disabled','false');
+                }
+            }
+        } );
+
+        list2.init( {
+            'columns' : columns,
+            'map_row_to_columns' : column_mapper_func,
+            'on_select' : function(ev) {
+                JSAN.use('util.functional'); var sel = list1.retrieve_selection();
+                selected2 = util.functional.map_list( sel, function(o) { return JSON2js(o.getAttribute('retrieve_id')); });
+                if (selected2.length == 0) { 
+                    cmd_retrieve_patron2.setAttribute('disabled','true');
+                } else { 
+                    cmd_retrieve_patron2.setAttribute('disabled','false');
+                }
+            }
+        } );
+
+    } catch(E) {
+
+        try { error.standard_unexpected_error_alert('admin/work_log.xul,init_lists():',E); } catch(F) { alert(E); }
+    }
+}
+
+function populate_lists() {
+    try {
+        list1.clear();
+        data.stash_retrieve();
+        if (data.work_log) {
+            for (var i = 0; i < data.work_log.length; i++ ) { 
+                list1.append( data.work_log[i] );
+            }
+        }
+        list2.clear();
+        if (data.patron_log) {
+            for (var i = 0; i < data.patron_log.length; i++ ) { 
+                list2.append( data.patron_log[i] );
+            }
+        }
+    } catch(E) {
+        try { error.standard_unexpected_error_alert('admin/work_log.xul,populate_lists():',E); } catch(F) { alert(E); }
+    }
+}
+
+function set_behavior() {
+    try {
+        var cmd_refresh = document.getElementById('cmd_refresh');
+        var cmd_retrieve_item = document.getElementById('cmd_retrieve_item');
+        var cmd_retrieve_patron1 = document.getElementById('cmd_retrieve_patron1');
+        var cmd_retrieve_patron2 = document.getElementById('cmd_retrieve_patron2');
+
+        if (cmd_refresh) cmd_refresh.addEventListener('command', function() { populate_lists(); }, false);
+
+        function gen_patron_retrieval_func(which) {
+            return function(ev) {
+               try {
+                    var selected = which == 1 ? selected1 : selected2;
+                    var seen = {};
+                    for (var i = 0; i < selected.length; i++) {
+                        var patron_id = selected[i].au_id;
+                        if (typeof patron_id == 'null') continue;
+                        if (seen[patron_id]) continue; seen[patron_id] = true;
+                        xulG.new_patron_tab(
+                            {},
+                            { 'id' : patron_id }
+                        );
+                    }
+                } catch(E) {
+                    error.standard_unexpected_error_alert('Error in work_log.js, patron_retrieval_func():',E);
+                }
+            };
+        }
+        if (cmd_retrieve_patron1) cmd_retrieve_patron1.addEventListener('command', gen_patron_retrieval_func(1), false);
+        if (cmd_retrieve_patron2) cmd_retrieve_patron2.addEventListener('command', gen_patron_retrieval_func(2), false);
+
+        if (cmd_retrieve_item) cmd_retrieve_item.addEventListener(
+            'command',
+            function(ev) {
+                try {
+                    var seen = {}; var barcodes = [];
+                    for (var i = 0; i < selected1.length; i++) {
+                        var barcode = selected1[i].acp_barcode;
+                        if (typeof barcode == 'null') continue;
+                        if (seen[barcode]) continue; seen[barcode] = true;
+                        barcodes.push( barcode );
+                    }
+                    if (barcodes.length > 0) {
+                        xulG.new_tab(
+                            urls.XUL_COPY_STATUS,
+                            {},
+                            { 'barcodes' : barcodes }
+                        );
+                    }
+                } catch(E) {
+                    error.standard_unexpected_error_alert('Error in work_log.js, retrieve_item():',E);
+                }
+            },
+            false
+        );
+
+    } catch(E) {
+        try { error.standard_unexpected_error_alert('admin/work_log.xul,set_behavior():',E); } catch(F) { alert(E); }
+    }
+}
+
diff --git a/Open-ILS/xul/staff_client/server/admin/work_log.xul b/Open-ILS/xul/staff_client/server/admin/work_log.xul
new file mode 100644 (file)
index 0000000..a96c1cd
--- /dev/null
@@ -0,0 +1,75 @@
+<?xml version="1.0"?>
+<!-- Application: Evergreen Staff Client -->
+<!-- Screen: Display log of recent staff actions -->
+
+<!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
+<!-- STYLESHEETS -->
+<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
+<?xml-stylesheet href="/xul/server/skin/global.css" type="text/css"?>
+
+<!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
+<!-- LOCALIZATION -->
+<!DOCTYPE window PUBLIC "" ""[
+       <!--#include virtual="/opac/locale/${locale}/lang.dtd"-->
+]>
+
+<!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
+<!-- OVERLAYS -->
+<?xul-overlay href="/xul/server/OpenILS/util_overlay.xul"?>
+
+<window id="work_log_win" 
+       onload="try { my_init(); font_helper(); } catch(E) { alert(E); }"
+       xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+       <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
+       <!-- BEHAVIOR -->
+       <script type="text/javascript">
+               var myPackageDir = 'open_ils_staff_client'; var IAMXUL = true;
+       </script>
+       <scripts id="openils_util_scripts"/>
+    <messagecatalog id="circStrings" src="/xul/server/locale/<!--#echo var='locale'-->/circ.properties" />
+
+       <script type="text/javascript" src="/xul/server/main/JSAN.js"/>
+       <script type="text/javascript" src="work_log.js"/>
+
+    <vbox flex="1">
+        <toolbox>
+            <toolbar>
+                <label value="&staff.admin.work_log.list1.header;" />
+                <spacer flex="1"/>
+                <toolbarbutton id="refresh_btn" label="&staff.admin.work_log.refresh_btn.label;" accesskey="&staff.admin.work_log.refresh_btn.accesskey;" command="cmd_refresh" style="-moz-user-focus: normal" />
+                <toolbarbutton label="&staff.admin.work_log.list1.retrieve_item_btn.label;" accesskey="&staff.admin.work_log.list1.retrieve_item_btn.accesskey;" command="cmd_retrieve_item" style="-moz-user-focus: normal" />
+                <toolbarbutton label="&staff.admin.work_log.list1.retrieve_patron_btn.label;" accesskey="&staff.admin.work_log.list1.retrieve_patron_btn.accesskey;" command="cmd_retrieve_patron1" style="-moz-user-focus: normal" />
+            </toolbar>
+        </toolbox>
+        <tree id="work_action_log" flex="1" enableColumnDrag="true" context="work_log_actions"/>
+        <splitter><grippy/></splitter>
+        <toolbox>
+            <toolbar>
+                <label value="&staff.admin.work_log.list2.header;" />
+                <spacer flex="1"/>
+                <toolbarbutton label="&staff.admin.work_log.list2.retrieve_patron_btn.label;" accesskey="&staff.admin.work_log.list2.retrieve_patron_btn.accesskey;" command="cmd_retrieve_patron2" style="-moz-user-focus: normal" />
+            </toolbar>
+        </toolbox>
+        <tree id="work_patron_log" flex="1" enableColumnDrag="true" context="patron_actions"/>
+    </vbox>
+
+    <popupset>
+        <popup id="work_log_actions">
+            <menuitem label="&staff.admin.work_log.list1.retrieve_item_btn.label;" accesskey="&staff.admin.work_log.list1.retrieve_item_btn.accesskey;" command="cmd_retrieve_item" />
+            <menuitem label="&staff.admin.work_log.list1.retrieve_patron_btn.label;" accesskey="&staff.admin.work_log.list1.retrieve_patron_btn.accesskey;" command="cmd_retrieve_patron1" />
+        </popup>
+        <popup id="patron_actions">
+            <menuitem label="&staff.admin.work_log.list2.retrieve_patron_btn.label;" accesskey="&staff.admin.work_log.list2.retrieve_patron_btn.accesskey;" command="cmd_retrieve_patron2" />
+        </popup>
+    </popupset>
+
+    <commandset>
+        <command id="cmd_refresh" />
+        <command id="cmd_retrieve_item" />
+        <command id="cmd_retrieve_patron1" />
+        <command id="cmd_retrieve_patron2" />
+    </commandset>
+
+</window>
+
index 3e080db..604dfb4 100644 (file)
@@ -429,6 +429,22 @@ circ.checkout.prototype = {
                                                        //I could override map_row_to_column here
                                                        }
                                                );
+                        obj.error.work_log( 
+                            document.getElementById('circStrings').getFormattedString(
+                                'staff.circ.work_log_checkout.message',
+                                [
+                                    ses('staff_usrname'),
+                                    xulG.patron.family_name(),
+                                    xulG.patron.card().barcode(),
+                                    checkout.payload.copy.barcode()
+                                ]
+                            ), {
+                                'au_id' : xulG.patron.id(),
+                                'au_family_name' : xulG.patron.family_name(),
+                                'au_barcode' : xulG.patron.card().barcode(),
+                                'acp_barcode' : checkout.payload.copy.barcode()
+                            }
+                        );
                                                document.getElementById('msg_area').removeChild(x);
                                                /*
                                                if (typeof obj.on_checkout == 'function') {
index 23e88f6..16aa48d 100644 (file)
@@ -7,7 +7,7 @@ circ.util = {};
 circ.util.EXPORT_OK    = [
        'offline_checkout_columns', 'offline_checkin_columns', 'offline_renew_columns', 'offline_inhouse_use_columns',
        'columns', 'hold_columns', 'checkin_via_barcode', 'std_map_row_to_columns',
-       'show_last_few_circs', 'abort_transits', 'transit_columns', 'renew_via_barcode'
+       'show_last_few_circs', 'abort_transits', 'transit_columns', 'work_log_columns', 'renew_via_barcode'
 ];
 circ.util.EXPORT_TAGS  = { ':all' : circ.util.EXPORT_OK };
 
@@ -1154,6 +1154,62 @@ circ.util.columns = function(modify,params) {
        return c.sort( function(a,b) { if (a.label < b.label) return -1; if (a.label > b.label) return 1; return 0; } );
 };
 
+circ.util.work_log_columns = function(modify,params) {
+
+       JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
+
+       var c = [
+               {
+                       'persist' : 'hidden width ordinal',
+                       'id' : 'message',
+                       'label' : document.getElementById('circStrings').getString('staff.circ.work_log_column.message'),
+                       'flex' : 3,
+                       'primary' : true,
+                       'hidden' : false,
+                       'render' : function(my) { return my.message; }
+               },
+               {
+                       'persist' : 'hidden width ordinal',
+                       'id' : 'when',
+                       'label' : document.getElementById('circStrings').getString('staff.circ.work_log_column.when'),
+                       'flex' : 1,
+                       'primary' : false,
+                       'hidden' : false,
+                       'render' : function(my) { return String( my.when ); }
+               }
+
+       ];
+       for (var i = 0; i < c.length; i++) {
+               if (modify[ c[i].id ]) {
+                       for (var j in modify[ c[i].id ]) {
+                               c[i][j] = modify[ c[i].id ][j];
+                       }
+               }
+       }
+       if (params) {
+               if (params.just_these) {
+                       JSAN.use('util.functional');
+                       var new_c = [];
+                       for (var i = 0; i < params.just_these.length; i++) {
+                               var x = util.functional.find_list(c,function(d){return(d.id==params.just_these[i]);});
+                               new_c.push( function(y){ return y; }( x ) );
+                       }
+                       c = new_c;
+               }
+               if (params.except_these) {
+                       JSAN.use('util.functional');
+                       var new_c = [];
+                       for (var i = 0; i < c.length; i++) {
+                               var x = util.functional.find_list(params.except_these,function(d){return(d==c[i].id);});
+                               if (!x) new_c.push(c[i]);
+                       }
+                       c = new_c;
+               }
+
+       }
+       return c.sort( function(a,b) { if (a.label < b.label) return -1; if (a.label > b.label) return 1; return 0; } );
+};
+
 circ.util.transit_columns = function(modify,params) {
 
        JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
index 8e1fa38..f7223c3 100644 (file)
@@ -322,6 +322,9 @@ staff.circ.utils.estimated_wait=Estimated Wait Time
 staff.circ.utils.potential_copies=Potential Copies 
 staff.circ.utils.queue_position=Queue Position
 staff.circ.utils.total_holds=Total Number of Holds
+staff.circ.work_log_column.message=Message
+staff.circ.work_log_column.when=When
+staff.circ.work_log_checkout.message=%1$s circulated %4$s to %3$s (%2$s)
 staff.circ.checkin.hold_capture=Hold Capture
 staff.circ.checkin.check_in.tab=Item Check In
 staff.circ.checkin.error=Check In Failed (in circ.util.checkin) (%1$s): 
index 455381e..fdd43d6 100644 (file)
@@ -44,6 +44,7 @@ patron.display.prototype = {
                                { 
                                        'set_tab' : xulG.set_tab,
                                        'patron_id' : obj.patron.id(),
+                    'patron' : obj.patron,
                                        'check_stop_checkouts' : function() { return obj.check_stop_checkouts(); },
                                        'on_list_change' : function(checkout) {
                                                netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");