Ability to add records to permanent bookbags in TPAC.
authorJason Stephenson <jason@sigio.com>
Wed, 11 Jul 2012 12:59:48 +0000 (08:59 -0400)
committerDan Scott <dscott@laurentian.ca>
Sun, 22 Jul 2012 05:22:22 +0000 (01:22 -0400)
Add an actor usr setting for holding the name of a default book
list: opac.default_list.

Add a button on the my list interface to choose a list should as
the default list for adding titles.  There is presently no way to
unset a default menu, though the default can be changed to any
other menu at any time by clicking that list's button.

Modify opac/record and opac/results so that if a patron is logged
in their my lists will populate a menu.  This menu will include
options to add to a temporary list, the default list (if any), up
to 10 of the user's other lists, to add to a newly created list,
or to see all of their lists and add to one that does not appear
on the menu.

Adding to a temporary list will function the same as adding to a
list does prior to this enhancement.

Adding to a list chosen from the menu will add the record to that
list, and return the user to the search results or record page
that they were looking at.

Choosing to add to a new list will take the user to their "my
lists" page where they can create a new list.  After the list is
created, the record they wanted to add will be added to the new
list and they will be returned to the search results or record
that they were looking at.

Choosing the "see all" menu option will also take the user to
their "my lists" page.  However, all of their bookbags will be
visible and not just the normal limit of 10.  Their will be a
button next to each list's name with the text "Add to this list."
When the user clicks one of those buttons, the record will be
added to that list and the user's session redirected back to
their search or result page.

The user will have the option to create a new list when viewing
all of their lists.

The user will also be able to use the "Add to this list" feature
when they have chosen the "Add to new list" menu option.  This is
done from simplicity in the design, but also allows the user to
change their mind at the last second.

If a patron is not logged in, the add to my list will appear the
same as it does prior to this development.  It will continue to
function as it does prior to this development.

Add coust for opac.patron_temporary_list_warn to let an ou enable
warning users when adding records to a temporary book bag.

Add cust opac.temporary_list_no_warn to let patrons disable
the warning for themselves.

Add the opac.default_list usr_setting_type. This will be used to track a
user's default bookbag.

Add the upgrade script to create new coust and custs.

Insert coust (opac.patron.temporary_list_warn) and cust
(opac.temporary_list_no_warn, opac.default_list) into the respective
tables.

Add release notes for add to permanent bookbag feature.

Add a warning when the user adds a record to a temporary list.

TPAC has been modified so that a user will see a warning before adding
a record to a temporary bookbag.  This message serves to inform the
user that they are adding to a temporary list that will disappear when
their session ends.

A new org. unit setting has been added,
opac.patron.temporary_list_warn, that will enable this warning when
set.  Sites may choose not to display this warning.

The user may also set a preference in their search preferences to
disable this warning.  The setting only works when a user is logged
in, of course.

Add release notes for the temporary list warning feature.

Signed-off-by: Jason Stephenson <jason@sigio.com>
Signed-off-by: Dan Scott <dscott@laurentian.ca>
Signed-off-by: Ben Shum <bshum@biblio.org>
Signed-off-by: Dan Scott <dscott@laurentian.ca>

16 files changed:
Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader.pm
Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Account.pm
Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Container.pm
Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Record.pm
Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Search.pm
Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Util.pm
Open-ILS/src/sql/Pg/950.data.seed-values.sql
Open-ILS/src/sql/Pg/upgrade/XXXX.data.add-to-permanent-bookbag.sql [new file with mode: 0644]
Open-ILS/src/templates/opac/myopac/lists.tt2
Open-ILS/src/templates/opac/myopac/prefs_settings.tt2
Open-ILS/src/templates/opac/parts/record/summary.tt2
Open-ILS/src/templates/opac/parts/result/table.tt2
Open-ILS/src/templates/opac/temp_warn.tt2 [new file with mode: 0644]
Open-ILS/web/css/skin/default/opac/style.css
docs/RELEASE_NOTES_NEXT/add-to-permanent-bookbag.txt [new file with mode: 0644]
docs/RELEASE_NOTES_NEXT/warn-when-adding-to-a-temporary-bookbag.txt [new file with mode: 0644]

index 01cae1c..9d78bda 100644 (file)
@@ -127,6 +127,8 @@ sub load {
     return $self->load_mylist_move if $path =~ m|opac/mylist/move|;
     return $self->load_mylist if $path =~ m|opac/mylist|;
     return $self->load_cache_clear if $path =~ m|opac/cache/clear|;
+    return $self->load_temp_warn_post if $path =~ m|opac/temp_warn/post|;
+    return $self->load_temp_warn if $path =~ m|opac/temp_warn|;
 
     # ----------------------------------------------------------------
     #  Everything below here requires SSL
index 8e40799..07db754 100644 (file)
@@ -257,6 +257,48 @@ sub fetch_optin_prefs {
     return [map { {cust => $_, value => $user_set->{$_->name} } } @$opt_ins];
 }
 
+sub _load_lists_and_settings {
+    my $self = shift;
+    my $e = $self->editor;
+    my $stat = $self->_load_user_with_prefs;
+    unless ($stat) {
+        my $exclude = 0;
+        my $setting_map = $self->ctx->{user_setting_map};
+        $exclude = $$setting_map{'opac.default_list'} if ($$setting_map{'opac.default_list'});
+        $self->ctx->{bookbags} = $e->search_container_biblio_record_entry_bucket(
+            [
+                {owner => $self->ctx->{user}->id, btype => 'bookbag', id => {'<>' => $exclude}}, {
+                    order_by => {cbreb => 'name'},
+                    limit => $self->cgi->param('limit') || 10,
+                    offset => $self->cgi->param('offset') || 0
+                }
+            ]
+        );
+        # We also want a total count of the user's bookbags.
+        my $q = {
+            'select' => { 'cbreb' => [ { 'column' => 'id', 'transform' => 'count', 'aggregate' => 'true', 'alias' => 'count' } ] },
+            'from' => 'cbreb',
+            'where' => { 'btype' => 'bookbag', 'owner' => $self->ctx->{user}->id }
+        };
+        my $r = $e->json_query($q);
+        $self->ctx->{bookbag_count} = $r->[0]->{'count'};
+        # Someone has requested that we use the default list's name
+        # rather than "Default List."
+        if ($exclude) {
+            $q = {
+                'select' => {'cbreb' => ['name']},
+                'from' => 'cbreb',
+                'where' => {'id' => $exclude}
+            };
+            $r = $e->json_query($q);
+            $self->ctx->{default_bookbag} = $r->[0]->{'name'};
+        }
+    } else {
+        return $stat;
+    }
+    return undef;
+}
+
 sub update_optin_prefs {
     my $self = shift;
     my $user_prefs = shift;
@@ -351,6 +393,7 @@ sub load_myopac_prefs_settings {
         opac.hits_per_page
         opac.default_search_location
         opac.default_pickup_location
+        opac.temporary_list_no_warn
     /;
 
     my $stat = $self->_load_user_with_prefs;
@@ -1655,7 +1698,10 @@ sub load_myopac_bookbags {
         $e->rollback;
         return Apache2::Const::HTTP_INTERNAL_SERVER_ERROR;
     }
-    
+
+    # We load the user prefs to get their default bookbag.
+    $self->_load_user_with_prefs;
+
     # If the user wants a specific bookbag's items, load them.
     # XXX add bookbag item paging support
 
@@ -1709,6 +1755,16 @@ sub load_myopac_bookbags {
         }
     }
 
+    # If we have add_rec, we got here from the "Add to new list"
+    # or "See all" popmenu items.
+    if (my $add_rec = $self->cgi->param('add_rec')) {
+        $self->ctx->{add_rec} = $add_rec;
+        $self->ctx->{where_from} = $self->ctx->{referer};
+        if ( my $anchor = $self->cgi->param('anchor') ) {
+            $self->ctx->{where_from} =~ s/#.*|$/#$anchor/;
+        }
+    }
+
     $e->rollback;
     return Apache2::Const::OK;
 }
@@ -1726,7 +1782,7 @@ sub load_myopac_bookbag_update {
     $action = 'save_notes' if $cgi->param('save_notes');
     $action ||= $cgi->param('action');
 
-    $list_id ||= $cgi->param('list');
+    $list_id ||= $cgi->param('list') || $cgi->param('bbid');
 
     my @add_rec = $cgi->param('add_rec') || $cgi->param('record');
     my @selected_item = $cgi->param('selected_item');
@@ -1755,9 +1811,20 @@ sub load_myopac_bookbag_update {
         $list->owner($e->requestor->id);
         $list->btype('bookbag');
         $list->pub($shared ? 't' : 'f');
-        $success = $U->simplereq('open-ils.actor', 
-            'open-ils.actor.container.create', $e->authtoken, 'biblio', $list)
-
+        $success = $U->simplereq('open-ils.actor',
+            'open-ils.actor.container.create', $e->authtoken, 'biblio', $list);
+        if (ref($success) ne 'HASH' && scalar @add_rec) {
+            $list_id = (ref($success)) ? $success->id : $success;
+            foreach my $add_rec (@add_rec) {
+                my $item = Fieldmapper::container::biblio_record_entry_bucket_item->new;
+                $item->bucket($list_id);
+                $item->target_biblio_record_entry($add_rec);
+                $success = $U->simplereq('open-ils.actor',
+                                         'open-ils.actor.container.item.create', $e->authtoken, 'biblio', $item);
+                last unless $success;
+            }
+            $url = $cgi->param('where_from') if ($success && $cgi->param('where_from'));
+        }
     } elsif($action eq 'place_hold') {
 
         # @hold_recs comes from anon lists redirect; selected_itesm comes from existing buckets
@@ -1791,7 +1858,21 @@ sub load_myopac_bookbag_update {
     if($action eq 'delete') {
         $success = $U->simplereq('open-ils.actor', 
             'open-ils.actor.container.full_delete', $e->authtoken, 'biblio', $list_id);
-
+        if ($success) {
+            # We check to see if we're deleting the user's default list.
+            $self->_load_user_with_prefs;
+            my $settings_map = $self->ctx->{user_setting_map};
+            if ($$settings_map{'opac.default_list'} == $list_id) {
+                # We unset the user's opac.default_list setting.
+                $success = $U->simplereq(
+                    'open-ils.actor',
+                    'open-ils.actor.patron.settings.update',
+                    $e->authtoken,
+                    $e->requestor->id,
+                    { 'opac.default_list' => 0 }
+                );
+            }
+        }
     } elsif($action eq 'show') {
         unless($U->is_true($list->pub)) {
             $list->pub('t');
@@ -1822,8 +1903,15 @@ sub load_myopac_bookbag_update {
                 'open-ils.actor.container.item.create', $e->authtoken, 'biblio', $item);
             last unless $success;
         }
-
-    } elsif($action eq 'del_item') {
+        # Redirect back where we came from if we have an anchor parameter:
+        if ( my $anchor = $cgi->param('anchor') ) {
+            $url = $self->ctx->{referer};
+            $url =~ s/#.*|$/#$anchor/;
+        } elsif ($cgi->param('where_from')) {
+            # Or, if we have a "where_from" parameter.
+            $url = $cgi->param('where_from');
+        }
+    } elsif ($action eq 'del_item') {
         foreach (@selected_item) {
             $success = $U->simplereq(
                 'open-ils.actor',
@@ -1834,6 +1922,22 @@ sub load_myopac_bookbag_update {
     } elsif ($action eq 'save_notes') {
         $success = $self->update_bookbag_item_notes;
         $url .= "&bbid=" . uri_escape($cgi->param("bbid")) if $cgi->param("bbid");
+    } elsif ($action eq 'make_default') {
+        $success = $U->simplereq(
+            'open-ils.actor',
+            'open-ils.actor.patron.settings.update',
+            $e->authtoken,
+            $list->owner,
+            { 'opac.default_list' => $list_id }
+        );
+    } elsif ($action eq 'remove_default') {
+        $success = $U->simplereq(
+            'open-ils.actor',
+            'open-ils.actor.patron.settings.update',
+            $e->authtoken,
+            $list->owner,
+            { 'opac.default_list' => 0 }
+        );
     }
 
     return $self->generic_redirect($url) if $success;
index ba7a6ce..481099f 100644 (file)
@@ -63,6 +63,12 @@ sub load_mylist_add {
         'open-ils.actor.anon_cache.set_value', 
         $cache_key, (ref $self)->ANON_CACHE_MYLIST, $list);
 
+    # Check if we need to warn patron about adding to a "temporary"
+    # list:
+    if ($self->check_for_temp_list_warning) {
+        return $self->mylist_warning_redirect($cache_key);
+    }
+
     return $self->mylist_action_redirect($cache_key);
 }
 
@@ -155,6 +161,38 @@ sub mylist_action_redirect {
     );
 }
 
+# called after an anon-cache / my list addition when we are configured
+# to show a warning to the user.
+
+sub mylist_warning_redirect {
+    my $self = shift;
+    my $cache_key = shift;
+
+    my $base_url = sprintf(
+        "%s://%s%s/temp_warn",
+        $self->cgi->https ? 'https' : 'http',
+        $self->apache->hostname,
+        $self->ctx->{opac_root}
+    );
+
+    my $redirect = $self->ctx->{referer};
+    if (my $anchor = $self->cgi->param('anchor')) {
+        $redirect =~ s/#.*|$/#$anchor/;
+    }
+
+    $base_url .= '?redirect_to=' . uri_escape($redirect);
+
+    return $self->generic_redirect(
+        $base_url,
+        $self->cgi->cookie(
+            -name => (ref $self)->COOKIE_ANON_CACHE,
+            -path => '/',
+            -value => ($cache_key) ? $cache_key : '',
+            -expires => ($cache_key) ? undef : '-1h'
+        )
+    );
+}
+
 sub load_mylist {
     my ($self) = shift;
     (undef, $self->ctx->{mylist}, $self->ctx->{mylist_marc_xml}) =
@@ -163,4 +201,24 @@ sub load_mylist {
     return Apache2::Const::OK;
 }
 
+sub load_temp_warn_post {
+    my $self = shift;
+    my $url = $self->cgi->param('redirect_to');
+    return $self->generic_redirect(
+        $url,
+        $self->cgi->cookie(
+            -name => 'no_temp_list_warn',
+            -path => '/',
+            -value => ($self->cgi->param('no_temp_list_warn')) ? '1' : '',
+            -expires => ($self->cgi->param('no_temp_list_warn')) ? undef : '-1h'
+        )
+    );
+}
+
+sub load_temp_warn {
+    my $self = shift;
+    $self->ctx->{'redirect_to'} = $self->cgi->param('redirect_to');
+    return Apache2::Const::OK;
+}
+
 1;
index c7e9b4d..67e6369 100644 (file)
@@ -49,6 +49,12 @@ sub load_record {
     $self->fetch_related_search_info($rec_id);
     $self->timelog("past related search info");
 
+    # Check for user and load lists and prefs
+    if ($self->ctx->{user}) {
+        $self->_load_lists_and_settings;
+        $self->timelog("load user lists and settings");
+    }
+
     # run copy retrieval in parallel to bib retrieval
     # XXX unapi
     my $cstore = OpenSRF::AppSession->create('open-ils.cstore');
index 0280266..36f3436 100644 (file)
@@ -458,6 +458,9 @@ sub load_rresults {
         return $stat if $stat;
     }
 
+    # load temporary_list settings for user and ou:
+    $self->_load_lists_and_settings if ($ctx->{user});
+
     # shove recs into context in search results order
     for my $rec_id (@$rec_ids) {
         push(
index db660fe..166875c 100644 (file)
@@ -545,4 +545,24 @@ sub load_search_filter_groups {
 }
 
 
+sub check_for_temp_list_warning {
+    my $self = shift;
+    my $ctx = $self->ctx;
+    my $cgi = $self->cgi;
+
+    my $lib = $self->_get_search_lib;
+    my $warn = ($ctx->{get_org_setting}->($lib || 1, 'opac.patron.temporary_list_warn')) ? 1 : 0;
+
+    if ($warn && $ctx->{user}) {
+        $self->_load_user_with_prefs;
+        my $map = $ctx->{user_setting_map};
+        $warn = 0 if ($$map{'opac.temporary_list_no_warn'});
+    }
+
+    # Check for a cookie disabling the warning.
+    $warn = 0 if ($warn && $cgi->cookie('no_temp_list_warn'));
+
+    return $warn;
+}
+
 1;
index 1c54059..d988a09 100644 (file)
@@ -11634,3 +11634,64 @@ INSERT into config.org_unit_setting_type
         'bool'
     );
 
+INSERT into config.org_unit_setting_type
+    (name, grp, label, description, datatype)
+    VALUES (
+        'opac.patron.temporary_list_warn',
+        'opac',
+        oils_i18n_gettext(
+            'opac.patron.temporary_list_warn',
+            'Warn patrons when adding to a temporary book list',
+            'coust',
+            'label'
+        ),
+        oils_i18n_gettext(
+            'opac.patron.temporary_list_warn',
+            'Present a warning dialog to the patron when a patron adds a book to a temporary book bag.',
+            'coust',
+            'description'
+        ),
+        'bool'
+    );
+
+INSERT INTO config.usr_setting_type
+    (name,grp,opac_visible,label,description,datatype)
+VALUES (
+    'opac.temporary_list_no_warn',
+    'opac',
+    TRUE,
+    oils_i18n_gettext(
+        'opac.temporary_list_no_warn',
+        'Opt out of warning when adding a book to a temporary book list',
+        'cust',
+        'label'
+    ),
+    oils_i18n_gettext(
+        'opac.temporary_list_no_warn',
+        'Opt out of warning when adding a book to a temporary book list',
+        'cust',
+        'description'
+    ),
+    'bool'
+);
+
+INSERT INTO config.usr_setting_type
+    (name,grp,opac_visible,label,description,datatype)
+VALUES (
+    'opac.default_list',
+    'opac',
+    FALSE,
+    oils_i18n_gettext(
+        'opac.default_list',
+        'Default list to use when adding to a bookbag',
+        'cust',
+        'label'
+    ),
+    oils_i18n_gettext(
+        'opac.default_list',
+        'Default list to use when adding to a bookbag',
+        'cust',
+        'description'
+    ),
+    'integer'
+);
diff --git a/Open-ILS/src/sql/Pg/upgrade/XXXX.data.add-to-permanent-bookbag.sql b/Open-ILS/src/sql/Pg/upgrade/XXXX.data.add-to-permanent-bookbag.sql
new file mode 100644 (file)
index 0000000..5c16367
--- /dev/null
@@ -0,0 +1,68 @@
+BEGIN;
+
+-- Check for the upgrade deps block
+SELECT evergreen.upgrade_deps_block_check('XXXX', :eg_version);
+
+INSERT into config.org_unit_setting_type
+    (name, grp, label, description, datatype)
+    VALUES (
+        'opac.patron.temporary_list_warn',
+        'opac',
+        oils_i18n_gettext(
+            'opac.patron.temporary_list_warn',
+            'Warn patrons when adding to a temporary book list',
+            'coust',
+            'label'
+        ),
+        oils_i18n_gettext(
+            'opac.patron.temporary_list_warn',
+            'Present a warning dialog to the patron when a patron adds a book to a temporary book bag.',
+            'coust',
+            'description'
+        ),
+        'bool'
+    );
+
+INSERT INTO config.usr_setting_type
+    (name,grp,opac_visible,label,description,datatype)
+VALUES (
+    'opac.temporary_list_no_warn',
+    'opac',
+    TRUE,
+    oils_i18n_gettext(
+        'opac.temporary_list_no_warn',
+        'Opt out of warning when adding a book to a temporary book list',
+        'cust',
+        'label'
+    ),
+    oils_i18n_gettext(
+        'opac.temporary_list_no_warn',
+        'Opt out of warning when adding a book to a temporary book list',
+        'cust',
+        'description'
+    ),
+    'bool'
+);
+
+INSERT INTO config.usr_setting_type
+    (name,grp,opac_visible,label,description,datatype)
+VALUES (
+    'opac.default_list',
+    'opac',
+    FALSE,
+    oils_i18n_gettext(
+        'opac.default_list',
+        'Default list to use when adding to a bookbag',
+        'cust',
+        'label'
+    ),
+    oils_i18n_gettext(
+        'opac.default_list',
+        'Default list to use when adding to a bookbag',
+        'cust',
+        'description'
+    ),
+    'integer'
+);
+
+COMMIT;
index 88972c6..e633688 100644 (file)
                     [%- INCLUDE "opac/parts/preserve_params.tt2"; %]
                     <input id="list_create_name" type="text" name="name" />
                     <input type="hidden" name="action" value="create" />
+                    [% IF ctx.add_rec %]
+                    <input type="hidden" name="add_rec" value="[% ctx.add_rec %]" />
+                    [% END %]
+                    [% IF ctx.where_from %]
+                    <input type="hidden" name="where_from" value="[% ctx.where_from %]" />
+                    [% END %]
                 </td>
                 <td>
                     <label for="list_create_shared">[% l('Share this list?') %]</label>
     [% IF ctx.bookbags.size %]
     <div class="header_middle">
         <span class="float-left">[% l('Saved Lists') %]</span>
+        [% IF limit < ctx.bookbag_count %]
         <span class='float-left' style='padding-left: 10px;'>
             <a href='[% mkurl(ctx.opac_root _ '/myopac/lists', {limit => limit, offset => (offset - limit)}) %]'
                 [% IF offset == 0 %] class='invisible' [% END %]><span class="nav_arrow_fix">&#9668;</span>[% l('Previous') %]</a>
-            [%# TODO: get total to prevent paging off then end of the list.. %]
             <a href='[% mkurl(ctx.opac_root _ '/myopac/lists', {limit => limit, offset => (offset + limit)}) %]'
                [% IF ctx.bookbags.size < limit %] class='invisible' [% END %] >[% l('Next') %]<span class="nav_arrow_fix">&#9658;</span></a>
         </span>
+        [% END %]
     </div>
     <div class="clear-both"></div>
 
                 <h2 class="bookbag-name"><a title="[% ltitle %]" href="[% url %]">[% bbag.name | html %]</a></h2>
                 [% IF bbag.description %]<div class="bookbag-description">[% bbag.description | html %]</div>[% END %]
             </div>
+            [% IF ctx.add_rec %]
+            <form action="[% mkurl(ctx.opac_root _ '/myopac/list/update', {}, 1) %]" method="POST">
+                <div class="bookbag-controls">
+                    <input type="hidden" name="action" value="add_rec" />
+                    <input type="hidden" name="list" value="[% bbag.id %]" />
+                    <input type="hidden" name="add_rec" value="[% ctx.add_rec %]" />
+                    [% IF ctx.where_from %]
+                    <input type="hidden" name="where_from" value="[% ctx.where_from %]" />
+                    [% END %]
+                    <input class="fixed" type="submit" value="[% l('Add to this list') %]" />
+                </div>
+            </form>
+            [% END %]
             <form action="[% mkurl(ctx.opac_root _ '/myopac/list/update') %]" method="POST">
                 <div class="bookbag-share">
                     <input type="hidden" name="list" value="[% bbag.id %]" />
                     <input type="submit" value="[% l('Download CSV') %]" />
                 </div>
             </form>
+            [% setting = 'opac.default_list'; %]
+            <form action="[% mkurl(ctx.opac_root _ '/myopac/list/update') %]" method="POST">
+                <div class="bookbag-controls">
+                    <input type="hidden" name="list" value="[% bbag.id %]" />
+                    [%- INCLUDE "opac/parts/preserve_params.tt2"; %]
+                    [% IF ctx.user_setting_map.$setting == bbag.id %]
+                    <input type="hidden" name="action" value="remove_default" />
+                    <input type="submit" value="[% l('Remove Default List') %]" />
+                    [% ELSE %]
+                    <input type="hidden" name="action" value="make_default" />
+                    <input type="submit" value="[% l('Make Default List') %]" />
+                    [% END %]
+                </div>
+            </form>
             <div class="bookbag-controls">
                 [% IF bbag.pub == 't'; %]
                 <a target='_blank' href='/opac/extras/feed/bookbag/rss2-full/[% bbag.id %]'><img
index b5d1f70..84b2554 100644 (file)
                             [% IF ctx.user_setting_map.$setting; %] checked='checked' [% END %]/>
                     </td>
                 </tr>
-
+                <tr>
+                    <td>[% l('Skip warning when adding to temporary book list?') %]</td>
+                    <td>
+                        [% setting = 'opac.temporary_list_no_warn' %]
+                        <input name='[% setting %]' type="checkbox"
+                            [% IF ctx.user_setting_map.$setting %] checked='checked' [% END %]/>
+                    </td>
+                </tr>
                 <!--
                 <tr>
                     <td>[% l("Default Font Size") %]</td>
index 062bf2f..16e55cf 100644 (file)
             class="place_hold">[% l('Place Hold') %]</span></a>
         </div>
         <div class="rdetail_aux_utils toggle_list">
-        [%-  
+        [%  IF ctx.user;
+            dsetting = "opac.default_list";
+            tclass = (ctx.user_setting_map.$dsetting) ? "temporary" :
+                         (ctx.bookbags.size) ? "temporary divider" : "temporary";
+            href = mkurl(ctx.opac_root _ '/mylist/add',
+                         {record => ctx.bre_id, anchor => ctx.bre_id}, stop_parms);
+        %]
+            <ul class="popmenu">
+            <li><a href="#" class="no-dec">
+                    <img src="[% ctx.media_prefix %]/images/clipboard.png" alt="" />
+                    [% l("Add to my list") %]
+                </a>
+            <ul>
+            <li class="[% tclass %]">
+                <a href="[% href %]">[% l('Temporary List') %]</a>
+            </li>
+            [% IF ctx.user_setting_map.$dsetting;
+               label = (ctx.default_bookbag) ? ctx.default_bookbag : l('Default List');
+               class = (ctx.bookbags.size) ? "default divider" : "default";
+               href = mkurl(ctx.opac_root _ '/myopac/list/update',
+                            {action => 'add_rec', list => ctx.user_setting_map.$dsetting,
+                             record => ctx.bre_id, anchor => ctx.bre_id}, stop_parms);
+            %]
+            <li class="[% class %]">
+                <a href="[% href %]">[% label %]</a>
+            </li>
+            [% END %]
+            [% IF ctx.bookbags.size;
+               i = 0;
+               FOREACH bag IN ctx.bookbags;
+                   href = mkurl(ctx.opac_root _ '/myopac/list/update',
+                                {action => 'add_rec', list => bag.id, record => ctx.bre_id,
+                                 anchor => ctx.bre_id}, stop_parms);
+                   i = i + 1;
+                   IF i == ctx.bookbags.size;
+            %]
+            <li class="divider">
+                [% ELSE %]
+            <li>
+                [% END %]
+               <a href="[% href %]">[% bag.name %]</a>
+            </li>
+            [%
+               END;
+               END
+            %]
+            <li>
+                <a href="[% mkurl(ctx.opac_root _ '/myopac/lists', {limit => ctx.bookbag_count, add_rec => ctx.bre_id}) %]">
+                [% l('See All') %]
+                </a>
+            </li>
+            <li class="new">
+                <a href="[% mkurl(ctx.opac_root _ '/myopac/lists', {add_rec => ctx.bre_id}, stop_parms) %]">
+                [% l('Add to new list') %]
+                </a>
+            </li>
+            </ul>
+            </li>
+            </ul>
+        [%  ELSE;
             operation = ctx.mylist.grep(ctx.bre_id).size ? "delete" : "add";
             label = (operation == "add") ? l("Add to my list") : l("Remove from my list"); 
         %]
@@ -38,6 +97,7 @@
                 <img src="[% ctx.media_prefix %]/images/clipboard.png" alt="" />
                 [% label %]
             </a>
+        [% END %]
         </div>
         <div class="rdetail_aux_utils">
             <img src="[% ctx.media_prefix %]/images/clipboard.png" alt="" />
index 21ccaa4..e16852b 100644 (file)
                                                                 alt=""/><span class="result_place_hold">[% l('Place Hold') %]</span></a>
                                                         </div>
                                                         <div class="results_aux_utils result_util">
-                                                            [%  
+                                                            [%  IF ctx.user;
+                                                                dsetting = "opac.default_list";
+                                                                tclass = (ctx.user_setting_map.$dsetting) ? "temporary" :
+                                                                           (ctx.bookbags.size) ? "temporary divider" : "temporary";
+                                                                 href = mkurl(ctx.opac_root _ '/mylist/add',
+                                                                              {record => rec.id, anchor => 'record_' _ rec.id}, 1);
+                                                            %]
+                                                                <ul class="popmenu">
+                                                                    <li><a href="#" class="no-dec">
+                                                                          <img src="[% ctx.media_prefix %]/images/clipboard.png" alt="" />
+                                                                          [% l("Add to my list") %]
+                                                                        </a>
+                                                                    <ul>
+                                                                    <li class="[% tclass %]">
+                                                                    <a href="[% href %]">[% l('Temporary List') %]</a>
+                                                                    </li>
+                                                                    [% IF ctx.user_setting_map.$dsetting;
+                                                                       class = (ctx.bookbags.size) ? "default divider" : "default";
+                                                                       label = (ctx.default_bookbag) ? ctx.default_bookbag : l('Default List');
+                                                                       href = mkurl(ctx.opac_root _ '/myopac/list/update',
+                                                                                {action => 'add_rec', list => ctx.user_setting_map.$dsetting,
+                                                                                 record => rec.id, anchor => 'record_' _ rec.id}, 1);
+                                                                    %]
+                                                                    <li class="[% class %]">
+                                                                    <a href="[% href %]">[% label %]</a>
+                                                                    </li>
+                                                                    [% END %]
+                                                                    [% IF ctx.bookbags.size;
+                                                                       i = 0;
+                                                                       FOREACH bag IN ctx.bookbags;
+                                                                           href = mkurl(ctx.opac_root _ '/myopac/list/update',
+                                                                                    {action => 'add_rec', list => bag.id, record => rec.id,
+                                                                                     anchor => 'record_' _ rec.id}, 1);
+                                                                           i = i + 1;
+                                                                           IF i == ctx.bookbags.size;
+                                                                    %]
+                                                                    <li class="divider">
+                                                                        [% ELSE %]
+                                                                    <li>
+                                                                        [% END %]
+                                                                    <a href="[% href %]">[% bag.name %]</a>
+                                                                    </li>
+                                                                    [%
+                                                                       END;
+                                                                       END
+                                                                    %]
+                                                                    <li>
+                                                                        <a href="[% mkurl(ctx.opac_root _ '/myopac/lists',
+                                                                                          {limit => ctx.bookbag_count, add_rec => rec.id,
+                                                                                           anchor => 'record_' _ rec.id}) %]">
+                                                                        [% l('See All') %]
+                                                                        </a>
+                                                                    </li>
+                                                                    <li class="new">
+                                                                    <a href="[% mkurl(ctx.opac_root _ '/myopac/lists',
+                                                                                      {add_rec => rec.id, anchor => 'record_' _ rec.id}, 0) %]">
+                                                                    [% l('Add to new list') %]
+                                                                    </a>
+                                                                    </li>
+                                                                    </ul>
+                                                                    </li>
+                                                                </ul>
+                                                            [%  ELSE;
                                                                 operation = ctx.mylist.grep(rec.id).size ? "delete" : "add";
                                                                 label = (operation == "add") ? l("Add to my list") : l("Remove from my list");
                                                                 href = mkurl(ctx.opac_root _ '/mylist/' _ operation, 
                                                                 <img src="[% ctx.media_prefix %]/images/clipboard.png" alt="" />
                                                                 [% label %]
                                                             </a>
+                                                            [% END %]
                                                         </div>
                                                         [% IF ENV.OILS_CONTENT_CAFE_USER %]
                                                         <div class="results_aux_utils result_util">
diff --git a/Open-ILS/src/templates/opac/temp_warn.tt2 b/Open-ILS/src/templates/opac/temp_warn.tt2
new file mode 100644 (file)
index 0000000..d6be0b3
--- /dev/null
@@ -0,0 +1,28 @@
+[%  PROCESS "opac/parts/header.tt2";
+    PROCESS "opac/parts/misc_util.tt2";
+    WRAPPER "opac/parts/base.tt2";
+    INCLUDE "opac/parts/topnav.tt2";
+    ctx.page_title = l("Temporary List Warning") %]
+    <div id="search-wrapper">
+        [% INCLUDE "opac/parts/searchbar.tt2" %]
+    </div>
+    <div id="content-wrapper">
+        <div id="main-content">
+             <p class="big-strong">[% l('You are adding to a temporary list.') %]
+                [% IF ctx.user ;
+                      l('This information will disappear when you logout, unless you save it to a permanent list.');
+                   ELSE;
+                      l('This information will disappear when you end your session, unless you login and save it to a permanent list.');
+                   END
+                %]</p>
+             <form method="POST" action="[% mkurl(ctx.opac_root _ '/temp_warn/post', {}, 1) %]">
+             <input type="hidden" name="redirect_to" value="[% ctx.redirect_to %]" />
+             <input type="checkbox" name="no_temp_list_warn" value="on" />
+             <label for="no_temp_list_warn">[% l('Do not show this warning again.') %]</label>
+             <br />
+             <input type="submit" class="fixed" value="[% l('OK') %]" />
+             </form>
+            <div class="common-full-pad"></div>        
+        </div>
+    </div>
+[% END %]
index 30bef30..a8fb879 100644 (file)
@@ -1465,3 +1465,75 @@ a.preflib_change {
 .ac_tab_selected { background-color: #417860; }
 .ac_tab_selected a { color: #FFF; }
 #ac_content { clear: both; width: 100%; margin-top: 10px; }
+
+/* Popmenu styles used for making css menus. */
+.popmenu {
+    margin: 0;
+    padding: 0;
+}
+.popmenu li {
+    list-style: none;
+}
+.popmenu li a {
+    display: block;
+    padding: 3px 5px;
+}
+.popmenu li ul {
+    display: none; 
+    width: 10em; /* Width to help Opera out */
+    background-color: #00593d;
+}
+.popmenu li:hover ul {
+    display: block;
+    position: absolute;
+    margin: 0;
+    padding: 0;
+    border-color: black;
+    border-width: 1px;
+    border-style: solid;
+}
+.popmenu li:hover li {
+    float: none;
+}
+.popmenu li:hover li a {
+    background-color: #00593d; 
+    color: #f0e0e0;
+}
+.popmenu li li a:hover {
+    background-color: #f0e0e0; 
+    color: #00593d;
+}
+/* Styles for the temporary list entry. */
+.popmenu li:hover li[class~="temporary"] a {
+    background-color: #00593d; 
+    color: #f0e0e0;
+}
+.popmenu li li[class~="temporary"] a:hover {
+    background-color: #f0e0e0; 
+    color: #00593d;
+}
+/* Styles for the default list entry. */
+.popmenu li:hover li[class~="default"] a {
+    background-color: #00593d; 
+    color: #f0e0e0;
+}
+.popmenu li li[class~="default"] a:hover {
+    background-color: #f0e0e0; 
+    color: #00593d;
+}
+/* Styles for the new list entry. */
+.popmenu li:hover li[class~="new"] a {
+    background-color: #00593d; 
+    color: #f0e0e0;
+}
+.popmenu li li[class~="new"] a:hover {
+    background-color: #f0e0e0; 
+    color: #00593d;
+}
+/* Style to add a divider on the menu. */
+.popmenu li li[class~="divider"] {
+    border-bottom-width: 1px;
+    border-bottom-color: black;
+    border-bottom-style: solid;
+}
+    
diff --git a/docs/RELEASE_NOTES_NEXT/add-to-permanent-bookbag.txt b/docs/RELEASE_NOTES_NEXT/add-to-permanent-bookbag.txt
new file mode 100644 (file)
index 0000000..c586c62
--- /dev/null
@@ -0,0 +1,67 @@
+Add to Permanent Bookbag
+------------------------
+
+TPAC was modified to allow a logged-in user to add records from search
+results and record summary screens to their permanent bookbags rather
+than to a temporary bookbag that goes away when logged out.
+
+Bookbag Selection Menu
+~~~~~~~~~~~~~~~~~~~~~~
+
+The search results and record summary screens were modified so that
+the "Add to my list" will show a menu when moused over by a logged-in
+user.  This menu will display the option to add to a temporary
+bookbag, the user's default list (if any), up to ten of the user's
+other bookbags, a "See all" option to allow the user to choose one of
+the bags not on the menu, and to create a new list and add the record
+to it.
+
+Choosing the temporary list from the menu will add the record to the
+temporary my list as TPAC does before the addition of this feature.
+
+Choosing a named list will add the record to the chosen list.
+
+Choosing "See all" or "Add to new list" will take the user to their My
+Lists page.  (The only difference being that "See all" will actually
+list all of the user's bookbags if they have more than the current
+limit.)  The My Lists page will have a new button "Add to this list"
+next to each of their existing lists.  In addition, if the user
+creates a new list on this screen, the selected record will
+automatically be added to this new list.
+
+You can tell all of the above is working if you are redirected to your
+search results or record summary after adding to a list.  If there was
+a problem, you will get either an error page or will see your My Lists
+page.
+
+Designating a Default Bookbag/list
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The user's My List screen has had a 'Make Default List' button added
+for each list.  Clicking the button will cause that list to be
+registered as the user's default list.  This is the list that will be
+added to when a user chooses the Default List option on the Add to my
+list menu in search or record summary.
+
+The current default list has a 'Remove Default List' button next to
+it.  Clicking this button will unset the default status of the list
+and return to a state of having no default list.
+
+One handy way that users may want to use this feature is to create a
+new list, and then designate it as the default.  This list could then
+be used to add records from searches based on a current topic of
+interest.  Changing the default list is so easy that users may want to
+do so when changing search topics in order to keep their results
+better organized.
+
+A Note on CSS Styles
+~~~~~~~~~~~~~~~~~~~~
+
+If a user has a bookbag with an overly long name, the end of it will
+jut out past the right margin of the menu in FireFox and several other
+browsers.  To change this behavior, you may want to edit the `.popmenu
+li:hover li a` css entry in `web/css/skin/default/opac/style.css` by
+adding an `overflow` property.  If you desire to have the longer names
+clipped to the size ofthe menu then add `overlow: hidden`.  If you
+prefer to have a scroll bar for oversized entries, then add `overflow:
+auto`.
diff --git a/docs/RELEASE_NOTES_NEXT/warn-when-adding-to-a-temporary-bookbag.txt b/docs/RELEASE_NOTES_NEXT/warn-when-adding-to-a-temporary-bookbag.txt
new file mode 100644 (file)
index 0000000..103ea48
--- /dev/null
@@ -0,0 +1,15 @@
+Warn When Adding to a Temporary Bookbag
+---------------------------------------
+
+TPAC has been modified so that a user will see a warning before adding
+a record to a temporary bookbag.  This message serves to inform the
+user that they are adding to a temporary list that will disappear when
+their session ends.
+
+A new org. unit setting has been added,
+opac.patron.temporary_list_warn, that will enable this warning when
+set.  Sites may choose not to display this warning.
+
+The user may also set a preference in their search preferences to
+disable this warning.  The setting only works when a user is logged
+in, of course.