From fd7752cfdcdb801779d1ffbc42e293443a2dff72 Mon Sep 17 00:00:00 2001 From: Jason Stephenson Date: Wed, 11 Jul 2012 08:59:48 -0400 Subject: [PATCH] Ability to add records to permanent bookbags in TPAC. 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 Signed-off-by: Dan Scott Signed-off-by: Ben Shum Signed-off-by: Dan Scott --- .../src/perlmods/lib/OpenILS/WWW/EGCatLoader.pm | 2 + .../lib/OpenILS/WWW/EGCatLoader/Account.pm | 120 +++++++++++++++++++-- .../lib/OpenILS/WWW/EGCatLoader/Container.pm | 58 ++++++++++ .../perlmods/lib/OpenILS/WWW/EGCatLoader/Record.pm | 6 ++ .../perlmods/lib/OpenILS/WWW/EGCatLoader/Search.pm | 3 + .../perlmods/lib/OpenILS/WWW/EGCatLoader/Util.pm | 20 ++++ Open-ILS/src/sql/Pg/950.data.seed-values.sql | 61 +++++++++++ .../upgrade/XXXX.data.add-to-permanent-bookbag.sql | 68 ++++++++++++ Open-ILS/src/templates/opac/myopac/lists.tt2 | 36 ++++++- .../src/templates/opac/myopac/prefs_settings.tt2 | 9 +- .../src/templates/opac/parts/record/summary.tt2 | 62 ++++++++++- Open-ILS/src/templates/opac/parts/result/table.tt2 | 65 ++++++++++- Open-ILS/src/templates/opac/temp_warn.tt2 | 28 +++++ Open-ILS/web/css/skin/default/opac/style.css | 72 +++++++++++++ .../add-to-permanent-bookbag.txt | 67 ++++++++++++ .../warn-when-adding-to-a-temporary-bookbag.txt | 15 +++ 16 files changed, 680 insertions(+), 12 deletions(-) create mode 100644 Open-ILS/src/sql/Pg/upgrade/XXXX.data.add-to-permanent-bookbag.sql create mode 100644 Open-ILS/src/templates/opac/temp_warn.tt2 create mode 100644 docs/RELEASE_NOTES_NEXT/add-to-permanent-bookbag.txt create mode 100644 docs/RELEASE_NOTES_NEXT/warn-when-adding-to-a-temporary-bookbag.txt diff --git a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader.pm b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader.pm index 01cae1cf22..9d78bdaf6b 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader.pm @@ -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 diff --git a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Account.pm b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Account.pm index 8e40799edd..07db754d15 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Account.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Account.pm @@ -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; diff --git a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Container.pm b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Container.pm index ba7a6cec8d..481099fe4e 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Container.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Container.pm @@ -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; diff --git a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Record.pm b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Record.pm index c7e9b4d29e..67e6369822 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Record.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Record.pm @@ -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'); diff --git a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Search.pm b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Search.pm index 0280266099..36f3436320 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Search.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Search.pm @@ -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( diff --git a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Util.pm b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Util.pm index db660fe614..166875c631 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Util.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Util.pm @@ -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; diff --git a/Open-ILS/src/sql/Pg/950.data.seed-values.sql b/Open-ILS/src/sql/Pg/950.data.seed-values.sql index 1c54059434..d988a09e91 100644 --- a/Open-ILS/src/sql/Pg/950.data.seed-values.sql +++ b/Open-ILS/src/sql/Pg/950.data.seed-values.sql @@ -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 index 0000000000..5c16367b32 --- /dev/null +++ b/Open-ILS/src/sql/Pg/upgrade/XXXX.data.add-to-permanent-bookbag.sql @@ -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; diff --git a/Open-ILS/src/templates/opac/myopac/lists.tt2 b/Open-ILS/src/templates/opac/myopac/lists.tt2 index 88972c6c22..e633688f12 100644 --- a/Open-ILS/src/templates/opac/myopac/lists.tt2 +++ b/Open-ILS/src/templates/opac/myopac/lists.tt2 @@ -19,6 +19,12 @@ [%- INCLUDE "opac/parts/preserve_params.tt2"; %] + [% IF ctx.add_rec %] + + [% END %] + [% IF ctx.where_from %] + + [% END %] @@ -57,13 +63,14 @@ [% IF ctx.bookbags.size %]
@@ -82,6 +89,19 @@

[% bbag.name | html %]

[% IF bbag.description %]
[% bbag.description | html %]
[% END %] + [% IF ctx.add_rec %] +
+
+ + + + [% IF ctx.where_from %] + + [% END %] + +
+
+ [% END %]
@@ -111,6 +131,20 @@
+ [% setting = 'opac.default_list'; %] +
+
+ + [%- INCLUDE "opac/parts/preserve_params.tt2"; %] + [% IF ctx.user_setting_map.$setting == bbag.id %] + + + [% ELSE %] + + + [% END %] +
+