Improve see from / see also handling in MARC editor authority menu
authordbs <dbs@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Tue, 4 Jan 2011 19:07:43 +0000 (19:07 +0000)
committerdbs <dbs@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Tue, 4 Jan 2011 19:07:43 +0000 (19:07 +0000)
(Backporting r19091 and r19092 from trunk)

The 2.0-style authorities use a browse menu that currently consists
of matches against the 1XX entries, which makes working with see from /
see also entries rather difficult. To prepare for an authority browse
method that does surface matches against 4xx and 5xx entries, we will
now display the 4xx and 5xx entries for a given authority record
immediately below the 1xx entry in the browse menu, with the entry
text italicized, aligned to the right, and prefixed with "See also" or
"See from" appropriately. This won't provide a perfect alphabetized
solution - we won't know which field provided the alphabetical browse
match, so the best we can do is present the 1xx in the main browse
menu and the 4xx / 5xx below - but it will provide access to the other
references.

We now display the 4xx fields in the authority summary / selector menu
along with the 5xx fields. As part of making the 4xx and 5xx fields
first-class entries in the context menu, 5xx subfields are no longer
appended to their 1xx field menu entry with a "/" in the context menu.

$0 subfields are no longer added to the 4xx and 5xx fields from the
authority summary / selector menu; if a user had selected a 5xx and the
$0 that had been added by the menu, the field would have incorrectly been
linked to the 1xx authority record. To link to a 5xx entry, for now the
workaround is for the user to select the 5xx subfield(s), "Apply Selected",
then right-click on the new subfield to generate a new authority context menu.
To improve the 5xx handling, we need to make the "See also" entry fire a new
authority context menu based on the 5xx contents so that the actual 1xx
authority record can be inserted and linked against.

Consider an authority record containing the following fields:

150 $a Infants
450 $a Babies
550 $a Children

The ASCII-ized authority context menu will now display:

Infants              ->
    See from: Babies ->
  See also: Children ->

The submenu in each case will currently lead to the authority record
for "Infants". If we teach the underlying authority browse and startswith
methods to return matches based on 4xx and 5xx fields instead of just 1xx
fields, then the menu triggered by a right-click on "Childs" might look
like:

Chickens             ->
Infants              ->
    See from: Babies ->
  See also: Children ->
Choking              ->

The main entry will be out of alphabetical order, which is not ideal,
but the linkage from the 5xx should at least be evident. (Also, this
suggests that when clicking on a 5xx entry in the authority menu is
changed to launch a new authority menu, it should use the 1xx-only
browse variant to avoid showing the record from which the user was
referred...)

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

Open-ILS/src/perlmods/OpenILS/Application/SuperCat.pm
Open-ILS/src/perlmods/OpenILS/WWW/SuperCat.pm
Open-ILS/xul/staff_client/server/cat/marcedit.js
Open-ILS/xul/staff_client/server/locale/en-US/cat.properties

index 0053f5c..4d64dae 100644 (file)
@@ -23,7 +23,7 @@ use base qw/OpenILS::Application/;
 # This is the client class, used for connecting to open-ils.storage
 use OpenSRF::AppSession;
 
-# This is an extention of Error.pm that supplies some error types to throw
+# This is an extension of Error.pm that supplies some error types to throw
 use OpenSRF::EX qw(:try);
 
 # This is a helper class for querying the OpenSRF Settings application ...
@@ -589,12 +589,12 @@ __PACKAGE__->register_method(
        api_level => 1,
        argc      => 1,
        signature =>
-               { desc     => "Returns a list of the requested org-scoped record ids held",
+               { desc     => "Returns a list of the requested org-scoped record IDs held",
                  params   =>
                        [ { name => 'value', desc => 'The target title', type => 'string' },
                          { name => 'org_unit', desc => 'The org unit shortname (or "-" or undef for global) to browse', type => 'string' },
                          { name => 'page_size', desc => 'Count of records to retrieve, default is 9', type => 'number' },
-                         { name => 'page', desc => 'The page of records retrieve, calculated based on page_size.  Can be positive, negative or 0.', type => 'number' },
+                         { name => 'page', desc => 'The page of records retrieved, calculated based on page_size.  Can be positive, negative or 0.', type => 'number' },
                          { name => 'statuses', desc => 'Array of statuses to filter copies by, optional and can be undef.', type => 'array' },
                          { name => 'locations', desc => 'Array of copy locations to filter copies by, optional and can be undef.', type => 'array' }, ],
                  'return' => { desc => 'Record IDs that have copies at the relevant org units', type => 'array' }
@@ -607,12 +607,12 @@ __PACKAGE__->register_method(
        api_level => 1,
        argc      => 1,
        signature =>
-               { desc     => "Returns a list of the requested org-scoped record ids held",
+               { desc     => "Returns a list of the requested org-scoped record IDs held",
                  params   =>
                        [ { name => 'value', desc => 'The target author', type => 'string' },
                          { name => 'org_unit', desc => 'The org unit shortname (or "-" or undef for global) to browse', type => 'string' },
                          { name => 'page_size', desc => 'Count of records to retrieve, default is 9', type => 'number' },
-                         { name => 'page', desc => 'The page of records retrieve, calculated based on page_size.  Can be positive, negative or 0.', type => 'number' },
+                         { name => 'page', desc => 'The page of records retrieved, calculated based on page_size.  Can be positive, negative or 0.', type => 'number' },
                          { name => 'statuses', desc => 'Array of statuses to filter copies by, optional and can be undef.', type => 'array' },
                          { name => 'locations', desc => 'Array of copy locations to filter copies by, optional and can be undef.', type => 'array' }, ],
                  'return' => { desc => 'Record IDs that have copies at the relevant org units', type => 'array' }
@@ -625,12 +625,12 @@ __PACKAGE__->register_method(
        api_level => 1,
        argc      => 1,
        signature =>
-               { desc     => "Returns a list of the requested org-scoped record ids held",
+               { desc     => "Returns a list of the requested org-scoped record IDs held",
                  params   =>
                        [ { name => 'value', desc => 'The target subject', type => 'string' },
                          { name => 'org_unit', desc => 'The org unit shortname (or "-" or undef for global) to browse', type => 'string' },
                          { name => 'page_size', desc => 'Count of records to retrieve, default is 9', type => 'number' },
-                         { name => 'page', desc => 'The page of records retrieve, calculated based on page_size.  Can be positive, negative or 0.', type => 'number' },
+                         { name => 'page', desc => 'The page of records retrieved, calculated based on page_size.  Can be positive, negative or 0.', type => 'number' },
                          { name => 'statuses', desc => 'Array of statuses to filter copies by, optional and can be undef.', type => 'array' },
                          { name => 'locations', desc => 'Array of copy locations to filter copies by, optional and can be undef.', type => 'array' }, ],
                  'return' => { desc => 'Record IDs that have copies at the relevant org units', type => 'array' }
@@ -643,12 +643,12 @@ __PACKAGE__->register_method(
        api_level => 1,
        argc      => 1,
        signature =>
-               { desc     => "Returns a list of the requested org-scoped record ids held",
+               { desc     => "Returns a list of the requested org-scoped record IDs held",
                  params   =>
                        [ { name => 'value', desc => 'The target topical subject', type => 'string' },
                          { name => 'org_unit', desc => 'The org unit shortname (or "-" or undef for global) to browse', type => 'string' },
                          { name => 'page_size', desc => 'Count of records to retrieve, default is 9', type => 'number' },
-                         { name => 'page', desc => 'The page of records retrieve, calculated based on page_size.  Can be positive, negative or 0.', type => 'number' },
+                         { name => 'page', desc => 'The page of records retrieved, calculated based on page_size.  Can be positive, negative or 0.', type => 'number' },
                          { name => 'statuses', desc => 'Array of statuses to filter copies by, optional and can be undef.', type => 'array' },
                          { name => 'locations', desc => 'Array of copy locations to filter copies by, optional and can be undef.', type => 'array' }, ],
                  'return' => { desc => 'Record IDs that have copies at the relevant org units', type => 'array' }
@@ -661,12 +661,12 @@ __PACKAGE__->register_method(
        api_level => 1,
        argc      => 1,
        signature =>
-               { desc     => "Returns a list of the requested org-scoped record ids held",
+               { desc     => "Returns a list of the requested org-scoped record IDs held",
                  params   =>
                        [ { name => 'value', desc => 'The target series', type => 'string' },
                          { name => 'org_unit', desc => 'The org unit shortname (or "-" or undef for global) to browse', type => 'string' },
                          { name => 'page_size', desc => 'Count of records to retrieve, default is 9', type => 'number' },
-                         { name => 'page', desc => 'The page of records retrieve, calculated based on page_size.  Can be positive, negative or 0.', type => 'number' },
+                         { name => 'page', desc => 'The page of records retrieved, calculated based on page_size.  Can be positive, negative or 0.', type => 'number' },
                          { name => 'statuses', desc => 'Array of statuses to filter copies by, optional and can be undef.', type => 'array' },
                          { name => 'locations', desc => 'Array of copy locations to filter copies by, optional and can be undef.', type => 'array' }, ],
                  'return' => { desc => 'Record IDs that have copies at the relevant org units', type => 'array' }
@@ -820,7 +820,7 @@ __PACKAGE__->register_method(
        argc      => 1,
        signature =>
                { desc     => <<"                 DESC",
-Returns a list of the requested org-scoped record ids held
+Returns a list of the requested org-scoped record IDs held
                  DESC
                  params   =>
                        [
@@ -867,11 +867,11 @@ __PACKAGE__->register_method(
        api_level => 1,
        argc      => 1,
        signature =>
-               { desc     => "Returns a list of the requested authority record ids held",
+               { desc     => "Returns a list of the requested authority record IDs held",
                  params   =>
                        [ { name => 'value', desc => 'The target title', type => 'string' },
                          { name => 'page_size', desc => 'Count of records to retrieve, default is 9', type => 'number' },
-                         { name => 'page', desc => 'The page of records retrieve, calculated based on page_size.  Can be positive, negative or 0.', type => 'number' }, ],
+                         { name => 'page', desc => 'The page of records retrieved, calculated based on page_size.  Can be positive, negative or 0.', type => 'number' }, ],
                  'return' => { desc => 'Authority Record IDs that are near the target string', type => 'array' }
                }
 );
@@ -882,11 +882,11 @@ __PACKAGE__->register_method(
        api_level => 1,
        argc      => 1,
        signature =>
-               { desc     => "Returns a list of the requested authority record ids held",
+               { desc     => "Returns a list of the requested authority record IDs held",
                  params   =>
                        [ { name => 'value', desc => 'The target author', type => 'string' },
                          { name => 'page_size', desc => 'Count of records to retrieve, default is 9', type => 'number' },
-                         { name => 'page', desc => 'The page of records retrieve, calculated based on page_size.  Can be positive, negative or 0.', type => 'number' }, ],
+                         { name => 'page', desc => 'The page of records retrieved, calculated based on page_size.  Can be positive, negative or 0.', type => 'number' }, ],
                  'return' => { desc => 'Authority Record IDs that are near the target string', type => 'array' }
                }
 );
@@ -897,11 +897,11 @@ __PACKAGE__->register_method(
        api_level => 1,
        argc      => 1,
        signature =>
-               { desc     => "Returns a list of the requested authority record ids held",
+               { desc     => "Returns a list of the requested authority record IDs held",
                  params   =>
                        [ { name => 'value', desc => 'The target subject', type => 'string' },
                          { name => 'page_size', desc => 'Count of records to retrieve, default is 9', type => 'number' },
-                         { name => 'page', desc => 'The page of records retrieve, calculated based on page_size.  Can be positive, negative or 0.', type => 'number' }, ],
+                         { name => 'page', desc => 'The page of records retrieved, calculated based on page_size.  Can be positive, negative or 0.', type => 'number' }, ],
                  'return' => { desc => 'Authority Record IDs that are near the target string', type => 'array' }
                }
 );
@@ -912,11 +912,71 @@ __PACKAGE__->register_method(
        api_level => 1,
        argc      => 1,
        signature =>
-               { desc     => "Returns a list of the requested authority record ids held",
+               { desc     => "Returns a list of the requested authority record IDs held",
                  params   =>
                        [ { name => 'value', desc => 'The target topical subject', type => 'string' },
                          { name => 'page_size', desc => 'Count of records to retrieve, default is 9', type => 'number' },
-                         { name => 'page', desc => 'The page of records retrieve, calculated based on page_size.  Can be positive, negative or 0.', type => 'number' }, ],
+                         { name => 'page', desc => 'The page of records retrieved, calculated based on page_size.  Can be positive, negative or 0.', type => 'number' }, ],
+                 'return' => { desc => 'Authority Record IDs that are near the target string', type => 'array' }
+               }
+);
+__PACKAGE__->register_method(
+       method    => 'general_authority_browse',
+       api_name  => 'open-ils.supercat.authority.title.refs.browse',
+       tag       => '130', subfield => 'a',
+       api_level => 1,
+       argc      => 1,
+       signature =>
+               { desc     => "Returns a list of the requested authority record IDs held, including see (4xx) and see also (5xx) references",
+                 params   =>
+                       [ { name => 'value', desc => 'The target title', type => 'string' },
+                         { name => 'page_size', desc => 'Count of records to retrieve, default is 9', type => 'number' },
+                         { name => 'page', desc => 'The page of records retrieved, calculated based on page_size.  Can be positive, negative or 0.', type => 'number' }, ],
+                 'return' => { desc => 'Authority Record IDs that are near the target string', type => 'array' }
+               }
+);
+__PACKAGE__->register_method(
+       method    => 'general_authority_browse',
+       api_name  => 'open-ils.supercat.authority.author.refs.browse',
+       tag       => [qw/100 110 111/], subfield => 'a',
+       api_level => 1,
+       argc      => 1,
+       signature =>
+               { desc     => "Returns a list of the requested authority record IDs held, including see (4xx) and see also (5xx) references",
+                 params   =>
+                       [ { name => 'value', desc => 'The target author', type => 'string' },
+                         { name => 'page_size', desc => 'Count of records to retrieve, default is 9', type => 'number' },
+                         { name => 'page', desc => 'The page of records retrieved, calculated based on page_size.  Can be positive, negative or 0.', type => 'number' }, ],
+                 'return' => { desc => 'Authority Record IDs that are near the target string', type => 'array' }
+               }
+);
+__PACKAGE__->register_method(
+       method    => 'general_authority_browse',
+       api_name  => 'open-ils.supercat.authority.subject.refs.browse',
+       tag       => [qw/148 150 151 155/], subfield => 'a',
+       api_level => 1,
+       argc      => 1,
+       signature =>
+               { desc     => "Returns a list of the requested authority record IDs held, including see (4xx) and see also (5xx) references",
+                 params   =>
+                       [ { name => 'value', desc => 'The target subject', type => 'string' },
+                         { name => 'page_size', desc => 'Count of records to retrieve, default is 9', type => 'number' },
+                         { name => 'page', desc => 'The page of records retrieved, calculated based on page_size.  Can be positive, negative or 0.', type => 'number' }, ],
+                 'return' => { desc => 'Authority Record IDs that are near the target string', type => 'array' }
+               }
+);
+__PACKAGE__->register_method(
+       method    => 'general_authority_browse',
+       api_name  => 'open-ils.supercat.authority.topic.refs.browse',
+       tag       => '150', subfield => 'a',
+       api_level => 1,
+       argc      => 1,
+       signature =>
+               { desc     => "Returns a list of the requested authority record IDs held, including see (4xx) and see also (5xx) references",
+                 params   =>
+                       [ { name => 'value', desc => 'The target topical subject', type => 'string' },
+                         { name => 'page_size', desc => 'Count of records to retrieve, default is 9', type => 'number' },
+                         { name => 'page', desc => 'The page of records retrieved, calculated based on page_size.  Can be positive, negative or 0.', type => 'number' }, ],
                  'return' => { desc => 'Authority Record IDs that are near the target string', type => 'array' }
                }
 );
@@ -945,6 +1005,16 @@ sub authority_tag_sf_browse {
 
        my $_storage = OpenSRF::AppSession->create( 'open-ils.cstore' );
 
+       # .refs variant includes 4xx and 5xx variants for see / see also
+       if ($self->api_name =~ /\.refs\./) {
+               my @ref_tags;
+               foreach my $tagname (@$tag) {
+                       push(@ref_tags, '4' . substr($tagname, 1, 2));
+                       push(@ref_tags, '5' . substr($tagname, 1, 2));
+               }
+               push(@$tag, @ref_tags);
+       }
+
        my @list = ();
 
        if ($page <= 0) {
@@ -990,7 +1060,7 @@ __PACKAGE__->register_method(
        argc      => 1,
        signature =>
                { desc     => <<"                 DESC",
-Returns a list of the requested authority record ids held
+Returns a list of the requested authority record IDs held
                  DESC
                  params   =>
                        [
@@ -1028,12 +1098,12 @@ __PACKAGE__->register_method(
        api_level => 1,
        argc      => 1,
        signature =>
-               { desc     => "Returns a list of the requested org-scoped record ids held",
+               { desc     => "Returns a list of the requested org-scoped record IDs held",
                  params   =>
                        [ { name => 'value', desc => 'The target title', type => 'string' },
                          { name => 'org_unit', desc => 'The org unit shortname (or "-" or undef for global) to browse', type => 'string' },
                          { name => 'page_size', desc => 'Count of records to retrieve, default is 9', type => 'number' },
-                         { name => 'page', desc => 'The page of records retrieve, calculated based on page_size.  Can be positive, negative or 0.', type => 'number' },
+                         { name => 'page', desc => 'The page of records retrieved, calculated based on page_size.  Can be positive, negative or 0.', type => 'number' },
                          { name => 'statuses', desc => 'Array of statuses to filter copies by, optional and can be undef.', type => 'array' },
                          { name => 'locations', desc => 'Array of copy locations to filter copies by, optional and can be undef.', type => 'array' }, ],
                  'return' => { desc => 'Record IDs that have copies at the relevant org units', type => 'array' }
@@ -1046,12 +1116,12 @@ __PACKAGE__->register_method(
        api_level => 1,
        argc      => 1,
        signature =>
-               { desc     => "Returns a list of the requested org-scoped record ids held",
+               { desc     => "Returns a list of the requested org-scoped record IDs held",
                  params   =>
                        [ { name => 'value', desc => 'The target author', type => 'string' },
                          { name => 'org_unit', desc => 'The org unit shortname (or "-" or undef for global) to browse', type => 'string' },
                          { name => 'page_size', desc => 'Count of records to retrieve, default is 9', type => 'number' },
-                         { name => 'page', desc => 'The page of records retrieve, calculated based on page_size.  Can be positive, negative or 0.', type => 'number' },
+                         { name => 'page', desc => 'The page of records retrieved, calculated based on page_size.  Can be positive, negative or 0.', type => 'number' },
                          { name => 'statuses', desc => 'Array of statuses to filter copies by, optional and can be undef.', type => 'array' },
                          { name => 'locations', desc => 'Array of copy locations to filter copies by, optional and can be undef.', type => 'array' }, ],
                  'return' => { desc => 'Record IDs that have copies at the relevant org units', type => 'array' }
@@ -1064,12 +1134,12 @@ __PACKAGE__->register_method(
        api_level => 1,
        argc      => 1,
        signature =>
-               { desc     => "Returns a list of the requested org-scoped record ids held",
+               { desc     => "Returns a list of the requested org-scoped record IDs held",
                  params   =>
                        [ { name => 'value', desc => 'The target subject', type => 'string' },
                          { name => 'org_unit', desc => 'The org unit shortname (or "-" or undef for global) to browse', type => 'string' },
                          { name => 'page_size', desc => 'Count of records to retrieve, default is 9', type => 'number' },
-                         { name => 'page', desc => 'The page of records retrieve, calculated based on page_size.  Can be positive, negative or 0.', type => 'number' },
+                         { name => 'page', desc => 'The page of records retrieved, calculated based on page_size.  Can be positive, negative or 0.', type => 'number' },
                          { name => 'statuses', desc => 'Array of statuses to filter copies by, optional and can be undef.', type => 'array' },
                          { name => 'locations', desc => 'Array of copy locations to filter copies by, optional and can be undef.', type => 'array' }, ],
                  'return' => { desc => 'Record IDs that have copies at the relevant org units', type => 'array' }
@@ -1082,12 +1152,12 @@ __PACKAGE__->register_method(
        api_level => 1,
        argc      => 1,
        signature =>
-               { desc     => "Returns a list of the requested org-scoped record ids held",
+               { desc     => "Returns a list of the requested org-scoped record IDs held",
                  params   =>
                        [ { name => 'value', desc => 'The target topical subject', type => 'string' },
                          { name => 'org_unit', desc => 'The org unit shortname (or "-" or undef for global) to browse', type => 'string' },
                          { name => 'page_size', desc => 'Count of records to retrieve, default is 9', type => 'number' },
-                         { name => 'page', desc => 'The page of records retrieve, calculated based on page_size.  Can be positive, negative or 0.', type => 'number' },
+                         { name => 'page', desc => 'The page of records retrieved, calculated based on page_size.  Can be positive, negative or 0.', type => 'number' },
                          { name => 'statuses', desc => 'Array of statuses to filter copies by, optional and can be undef.', type => 'array' },
                          { name => 'locations', desc => 'Array of copy locations to filter copies by, optional and can be undef.', type => 'array' }, ],
                  'return' => { desc => 'Record IDs that have copies at the relevant org units', type => 'array' }
@@ -1100,12 +1170,12 @@ __PACKAGE__->register_method(
        api_level => 1,
        argc      => 1,
        signature =>
-               { desc     => "Returns a list of the requested org-scoped record ids held",
+               { desc     => "Returns a list of the requested org-scoped record IDs held",
                  params   =>
                        [ { name => 'value', desc => 'The target series', type => 'string' },
                          { name => 'org_unit', desc => 'The org unit shortname (or "-" or undef for global) to browse', type => 'string' },
                          { name => 'page_size', desc => 'Count of records to retrieve, default is 9', type => 'number' },
-                         { name => 'page', desc => 'The page of records retrieve, calculated based on page_size.  Can be positive, negative or 0.', type => 'number' },
+                         { name => 'page', desc => 'The page of records retrieved, calculated based on page_size.  Can be positive, negative or 0.', type => 'number' },
                          { name => 'statuses', desc => 'Array of statuses to filter copies by, optional and can be undef.', type => 'array' },
                          { name => 'locations', desc => 'Array of copy locations to filter copies by, optional and can be undef.', type => 'array' }, ],
                  'return' => { desc => 'Record IDs that have copies at the relevant org units', type => 'array' }
@@ -1248,7 +1318,7 @@ __PACKAGE__->register_method(
        argc      => 1,
        signature =>
                { desc     => <<"                 DESC",
-Returns a list of the requested org-scoped record ids held
+Returns a list of the requested org-scoped record IDs held
                  DESC
                  params   =>
                        [
@@ -1295,11 +1365,11 @@ __PACKAGE__->register_method(
        api_level => 1,
        argc      => 1,
        signature =>
-               { desc     => "Returns a list of the requested authority record ids held",
+               { desc     => "Returns a list of the requested authority record IDs held",
                  params   =>
                        [ { name => 'value', desc => 'The target title', type => 'string' },
                          { name => 'page_size', desc => 'Count of records to retrieve, default is 9', type => 'number' },
-                         { name => 'page', desc => 'The page of records retrieve, calculated based on page_size.  Can be positive, negative or 0.', type => 'number' }, ],
+                         { name => 'page', desc => 'The page of records retrieved, calculated based on page_size.  Can be positive, negative or 0.', type => 'number' }, ],
                  'return' => { desc => 'Authority Record IDs that are near the target string', type => 'array' }
                }
 );
@@ -1310,11 +1380,11 @@ __PACKAGE__->register_method(
        api_level => 1,
        argc      => 1,
        signature =>
-               { desc     => "Returns a list of the requested authority record ids held",
+               { desc     => "Returns a list of the requested authority record IDs held",
                  params   =>
                        [ { name => 'value', desc => 'The target author', type => 'string' },
                          { name => 'page_size', desc => 'Count of records to retrieve, default is 9', type => 'number' },
-                         { name => 'page', desc => 'The page of records retrieve, calculated based on page_size.  Can be positive, negative or 0.', type => 'number' }, ],
+                         { name => 'page', desc => 'The page of records retrieved, calculated based on page_size.  Can be positive, negative or 0.', type => 'number' }, ],
                  'return' => { desc => 'Authority Record IDs that are near the target string', type => 'array' }
                }
 );
@@ -1325,11 +1395,11 @@ __PACKAGE__->register_method(
        api_level => 1,
        argc      => 1,
        signature =>
-               { desc     => "Returns a list of the requested authority record ids held",
+               { desc     => "Returns a list of the requested authority record IDs held",
                  params   =>
                        [ { name => 'value', desc => 'The target subject', type => 'string' },
                          { name => 'page_size', desc => 'Count of records to retrieve, default is 9', type => 'number' },
-                         { name => 'page', desc => 'The page of records retrieve, calculated based on page_size.  Can be positive, negative or 0.', type => 'number' }, ],
+                         { name => 'page', desc => 'The page of records retrieved, calculated based on page_size.  Can be positive, negative or 0.', type => 'number' }, ],
                  'return' => { desc => 'Authority Record IDs that are near the target string', type => 'array' }
                }
 );
@@ -1340,11 +1410,71 @@ __PACKAGE__->register_method(
        api_level => 1,
        argc      => 1,
        signature =>
-               { desc     => "Returns a list of the requested authority record ids held",
+               { desc     => "Returns a list of the requested authority record IDs held",
                  params   =>
                        [ { name => 'value', desc => 'The target topical subject', type => 'string' },
                          { name => 'page_size', desc => 'Count of records to retrieve, default is 9', type => 'number' },
-                         { name => 'page', desc => 'The page of records retrieve, calculated based on page_size.  Can be positive, negative or 0.', type => 'number' }, ],
+                         { name => 'page', desc => 'The page of records retrieved, calculated based on page_size.  Can be positive, negative or 0.', type => 'number' }, ],
+                 'return' => { desc => 'Authority Record IDs that are near the target string', type => 'array' }
+               }
+);
+__PACKAGE__->register_method(
+       method    => 'general_authority_startwith',
+       api_name  => 'open-ils.supercat.authority.title.refs.startwith',
+       tag       => '130', subfield => 'a',
+       api_level => 1,
+       argc      => 1,
+       signature =>
+               { desc     => "Returns a list of the requested authority record IDs held, including see (4xx) and see also (5xx) references",
+                 params   =>
+                       [ { name => 'value', desc => 'The target title', type => 'string' },
+                         { name => 'page_size', desc => 'Count of records to retrieve, default is 9', type => 'number' },
+                         { name => 'page', desc => 'The page of records retrieved, calculated based on page_size.  Can be positive, negative or 0.', type => 'number' }, ],
+                 'return' => { desc => 'Authority Record IDs that are near the target string', type => 'array' }
+               }
+);
+__PACKAGE__->register_method(
+       method    => 'general_authority_startwith',
+       api_name  => 'open-ils.supercat.authority.author.refs.startwith',
+       tag       => [qw/100 110 111/], subfield => 'a',
+       api_level => 1,
+       argc      => 1,
+       signature =>
+               { desc     => "Returns a list of the requested authority record IDs held, including see (4xx) and see also (5xx) references",
+                 params   =>
+                       [ { name => 'value', desc => 'The target author', type => 'string' },
+                         { name => 'page_size', desc => 'Count of records to retrieve, default is 9', type => 'number' },
+                         { name => 'page', desc => 'The page of records retrieved, calculated based on page_size.  Can be positive, negative or 0.', type => 'number' }, ],
+                 'return' => { desc => 'Authority Record IDs that are near the target string', type => 'array' }
+               }
+);
+__PACKAGE__->register_method(
+       method    => 'general_authority_startwith',
+       api_name  => 'open-ils.supercat.authority.subject.refs.startwith',
+       tag       => [qw/148 150 151 155/], subfield => 'a',
+       api_level => 1,
+       argc      => 1,
+       signature =>
+               { desc     => "Returns a list of the requested authority record IDs held, including see (4xx) and see also (5xx) references",
+                 params   =>
+                       [ { name => 'value', desc => 'The target subject', type => 'string' },
+                         { name => 'page_size', desc => 'Count of records to retrieve, default is 9', type => 'number' },
+                         { name => 'page', desc => 'The page of records retrieved, calculated based on page_size.  Can be positive, negative or 0.', type => 'number' }, ],
+                 'return' => { desc => 'Authority Record IDs that are near the target string', type => 'array' }
+               }
+);
+__PACKAGE__->register_method(
+       method    => 'general_authority_startwith',
+       api_name  => 'open-ils.supercat.authority.topic.refs.startwith',
+       tag       => '150', subfield => 'a',
+       api_level => 1,
+       argc      => 1,
+       signature =>
+               { desc     => "Returns a list of the requested authority record IDs held, including see (4xx) and see also (5xx) references",
+                 params   =>
+                       [ { name => 'value', desc => 'The target topical subject', type => 'string' },
+                         { name => 'page_size', desc => 'Count of records to retrieve, default is 9', type => 'number' },
+                         { name => 'page', desc => 'The page of records retrieved, calculated based on page_size.  Can be positive, negative or 0.', type => 'number' }, ],
                  'return' => { desc => 'Authority Record IDs that are near the target string', type => 'array' }
                }
 );
@@ -1362,6 +1492,16 @@ sub authority_tag_sf_startwith {
        my $offset = $limit * abs($page);
        my $_storage = OpenSRF::AppSession->create( 'open-ils.cstore' );
 
+       # .refs variant includes 4xx and 5xx variants for see / see also
+       if ($self->api_name =~ /\.refs\./) {
+               my @ref_tags;
+               foreach my $tagname (@$tag) {
+                       push(@ref_tags, '4' . substr($tagname, 1, 2));
+                       push(@ref_tags, '5' . substr($tagname, 1, 2));
+               }
+               push(@$tag, @ref_tags);
+       }
+
        my @list = ();
 
        if ($page < 0) {
@@ -1410,7 +1550,7 @@ __PACKAGE__->register_method(
        argc      => 1,
        signature =>
                { desc     => <<"                 DESC",
-Returns a list of the requested authority record ids held
+Returns a list of the requested authority record IDs held
                  DESC
                  params   =>
                        [
index bf54240..040b888 100644 (file)
@@ -165,7 +165,7 @@ sub child_init {
                        my $base = shift;
                        my $site = shift;
 
-                       $log->info("Creating record feed with params [$real_format, $record_list, $unapi, $site]");
+                                       $log->info("Creating record feed with params [$real_format, $record_list, $unapi, $site]");
                        my $feed = create_record_feed( 'record', $real_format, $record_list, $unapi, $site, undef, $real_format =~ /(-full|-uris)$/o ? 1 : 0 );
                        $feed->root( "$base/../" );
                        $feed->lib( $site );
@@ -181,10 +181,10 @@ sub child_init {
         }
     }
 
-    for my $browse_axis ( qw/authority.title authority.author authority.subject authority.topic/ ) {
-        for my $record_browse_format ( qw/marcxml/ ) {
+    for my $basic_axis ( qw/authority.title authority.author authority.subject authority.topic/ ) {
+        for my $browse_axis ( ($basic_axis, $basic_axis . ".refs") ) {
             {
-                my $__f = $record_browse_format;
+                my $__f = 'marcxml';
                 my $__a = $browse_axis;
 
                 $browse_types{$__a}{$__f} = sub {
@@ -196,7 +196,7 @@ sub child_init {
                        my $base = shift;
                        my $site = shift;
 
-                       $log->info("Creating record feed with params [$real_format, $record_list, $unapi, $site]");
+                                       $log->info("Creating record feed with params [$real_format, $record_list, $unapi, $site]");
                        my $feed = create_record_feed( 'authority', $real_format, $record_list, $unapi, $site, undef, $real_format =~ /-full$/o ? -1 : 0 );
                        $feed->root( "$base/../" );
                        $feed->link( next => $next => $feed->type );
index 9aed265..8e984ac 100644 (file)
@@ -2374,7 +2374,7 @@ function browseAuthority (sf_popup, menu_id, target, sf, limit, page) {
     }
 
     var url = '/opac/extras/browse/marcxml/'
-        + type
+        + type + '.refs'
         + '/1' // OU - currently unscoped
         + '/' + sf.toString()
         + '/' + page
@@ -2444,10 +2444,13 @@ function browseAuthority (sf_popup, menu_id, target, sf, limit, page) {
 
         dojo.query('record', records).forEach(function(record) {
             var main_text = '';
+            var see_from = [];
+            var see_also = [];
             var auth_id = dojox.xml.parser.textContent(dojo.query('datafield[tag="901"] subfield[code="c"]', record)[0]);
             var auth_org = dojox.xml.parser.textContent(dojo.query('controlfield[tag="003"]', record)[0]);
-            // we have grabbed the fields with tags beginning with 1 or 5 and iterate through the subfields
-            dojo.query('datafield[tag^="1"], datafield[tag^="5"]', record).forEach(function(field) {
+
+            // Grab the fields with tags beginning with 1 (main entries) and iterate through the subfields
+            dojo.query('datafield[tag^="1"]', record).forEach(function(field) {
                 dojo.query('subfield', field).forEach(function(subfield) {
                     if (main_text) {
                         main_text += ' / ';
@@ -2456,85 +2459,42 @@ function browseAuthority (sf_popup, menu_id, target, sf, limit, page) {
                 });
             });
 
-            /*
-             * 
-            if (! (main[0].parent().@tag == authority_tag_map[sf.parent().@tag][1]) ) return;
-            */
-
-            var grid = dojo.query('[name="authority-marc-template"]')[0].cloneNode(true);
-            grid.setAttribute('name','-none-');
-            grid.setAttribute('style','overflow:scroll');
-
-            var submenu = createMenu( { label : main_text } );
-
-            var popup = createMenuPopup({ flex : "1" });
-            submenu.appendChild(popup);
-
-            dojo.query('datafield[tag^="1"], datafield[tag^="5"]', record).forEach(function(field) {
-                var row = createRow(
-                    { },
-                    createLabel( { "value" : dojo.attr(field, 'tag') } ),
-                    createLabel( { "value" : dojo.attr(field, 'ind1') } ),
-                    createLabel( { "value" : dojo.attr(field, 'ind2') } )
-                );
-
-                var sf_box = createHbox();
+            // Grab the fields with tags beginning with 4 (see from entries) and iterate through the subfields
+            dojo.query('datafield[tag^="4"]', record).forEach(function(field) {
+                var see_text = '';
                 dojo.query('subfield', field).forEach(function(subfield) {
-                    sf_box.appendChild(
-                        createCheckbox(
-                            { "label"    : '\u2021' + dojo.attr(subfield, 'code') + ' ' + dojox.xml.parser.textContent(subfield),
-                              "subfield" : dojo.attr(subfield, 'code'),
-                              "tag"      : dojo.attr(field, 'tag'),
-                              "value"    : dojox.xml.parser.textContent(subfield)
-                            }
-                        )
-                    );
-                    row.appendChild(sf_box);
+                    if (see_text) {
+                        see_text += ' / ';
+                    }
+                    see_text += dojox.xml.parser.textContent(subfield);
                 });
-
-                // Append the authority linking subfield
-                sf_box.appendChild(
-                    createCheckbox(
-                        { "label"    : '\u2021' + '0' + ' (' + auth_org + ')' + auth_id,
-                          "subfield" : '0',
-                          "tag"      : dojo.attr(field, 'tag'),
-                          "value"    : '(' + auth_org + ')' + auth_id
-                        }
-                    )
-                );
-                row.appendChild(sf_box);
-
-                grid.lastChild.appendChild(row);
+                see_from.push($('catStrings').getFormattedString('staff.cat.marcedit.authority_see_from', [see_text]));
             });
 
-            grid.hidden = false;
-            popup.appendChild( grid );
-
-            popup.appendChild(
-                createMenuitem(
-                    { label : $('catStrings').getString('staff.cat.marcedit.apply_selected.label'),
-                      command : function (event) {
-                            applySelectedAuthority(event.target.previousSibling, target, sf);
-                            return true;
-                      }
+            // Grab the fields with tags beginning with 5 (see also entries) and iterate through the subfields
+            dojo.query('datafield[tag^="5"]', record).forEach(function(field) {
+                var see_text = '';
+                dojo.query('subfield', field).forEach(function(subfield) {
+                    if (see_text) {
+                        see_text += ' / ';
                     }
-                )
-            );
+                    see_text += dojox.xml.parser.textContent(subfield);
+                });
+                see_also.push($('catStrings').getFormattedString('staff.cat.marcedit.authority_see_also', [see_text]));
+            });
 
-            popup.appendChild( createComplexXULElement( 'menuseparator' ) );
+            buildAuthorityPopup(main_text, record, auth_org, auth_id, sf_popup, target, sf);
 
-            popup.appendChild(
-                createMenuitem(
-                    { label : $('catStrings').getString('staff.cat.marcedit.apply_full.label'),
-                      command : function (event) {
-                            applyFullAuthority(event.target.previousSibling.previousSibling.previousSibling, target, sf);
-                            return true;
-                      }
-                    }
-                )
-            );
+            dojo.forEach(see_from, function(entry_text) {
+                buildAuthorityPopup(entry_text, record, auth_org, auth_id, sf_popup, target, sf, "font-style: italic; margin-left: 2em;");
+            });
+
+            // To-do: instead of launching the standard selector menu, invoke
+            // a new authority search using the 5XX entry text
+            dojo.forEach(see_also, function(entry_text) {
+                buildAuthorityPopup(entry_text, record, auth_org, auth_id, sf_popup, target, sf, "font-style: italic; margin-left: 2em;");
+            });
 
-            sf_popup.appendChild( submenu );
         });
 
         if (sf_popup.childNodes.length == 0) {
@@ -2558,6 +2518,93 @@ function browseAuthority (sf_popup, menu_id, target, sf, limit, page) {
 
 }
 
+function buildAuthorityPopup (entry_text, record, auth_org, auth_id, sf_popup, target, sf, style) {
+    var grid = dojo.query('[name="authority-marc-template"]')[0].cloneNode(true);
+    grid.setAttribute('name','-none-');
+    grid.setAttribute('style','overflow:scroll');
+
+    var submenu = createMenu( { "label": entry_text } );
+
+    var popup = createMenuPopup({ "flex": "1" });
+    if (style) {
+        submenu.setAttribute('style', style);
+        popup.setAttribute('style', 'font-style: normal; margin-left: 0em;');
+    }
+    submenu.appendChild(popup);
+
+    dojo.query('datafield[tag^="1"], datafield[tag^="4"], datafield[tag^="5"]', record).forEach(function(field) {
+        buildAuthorityPopupSelector(field, grid, auth_org, auth_id);
+    });
+
+    grid.hidden = false;
+    popup.appendChild( grid );
+
+    popup.appendChild(
+        createMenuitem(
+            { label : $('catStrings').getString('staff.cat.marcedit.apply_selected.label'),
+              command : function (event) {
+                    applySelectedAuthority(event.target.previousSibling, target, sf);
+                    return true;
+              }
+            }
+        )
+    );
+
+    popup.appendChild( createComplexXULElement( 'menuseparator' ) );
+
+    popup.appendChild(
+        createMenuitem(
+            { label : $('catStrings').getString('staff.cat.marcedit.apply_full.label'),
+              command : function (event) {
+                    applyFullAuthority(event.target.previousSibling.previousSibling.previousSibling, target, sf);
+                    return true;
+              }
+            }
+        )
+    );
+
+    sf_popup.appendChild( submenu );
+}
+
+function buildAuthorityPopupSelector (field, grid, auth_org, auth_id) {
+    var row = createRow(
+        { },
+        createLabel( { "value" : dojo.attr(field, 'tag') } ),
+        createLabel( { "value" : dojo.attr(field, 'ind1') } ),
+        createLabel( { "value" : dojo.attr(field, 'ind2') } )
+    );
+
+    var sf_box = createHbox();
+    dojo.query('subfield', field).forEach(function(subfield) {
+        sf_box.appendChild(
+            createCheckbox(
+                { "label"    : '\u2021' + dojo.attr(subfield, 'code') + ' ' + dojox.xml.parser.textContent(subfield),
+                  "subfield" : dojo.attr(subfield, 'code'),
+                  "tag"      : dojo.attr(field, 'tag'),
+                  "value"    : dojox.xml.parser.textContent(subfield)
+                }
+            )
+        );
+        row.appendChild(sf_box);
+    });
+
+    // Append the authority linking subfield only for main entries
+    if (dojo.attr(field, 'tag').charAt(0) == '1') {
+        sf_box.appendChild(
+            createCheckbox(
+                { "label"    : '\u2021' + '0' + ' (' + auth_org + ')' + auth_id,
+                  "subfield" : '0',
+                  "tag"      : dojo.attr(field, 'tag'),
+                  "value"    : '(' + auth_org + ')' + auth_id
+                }
+            )
+        );
+    }
+    row.appendChild(sf_box);
+
+    grid.lastChild.appendChild(row);
+}
+
 function summarizeField(sf) {
     var source_f= {
         "tag": '',
index a93fb14..ddf3366 100644 (file)
@@ -222,6 +222,8 @@ staff.cat.copy_summary.yes=Yes
 staff.cat.copy_summary.no=No
 staff.cat.copy_summary.unset=<Unset>
 staff.cat.copy_summary.not_cataloged=Not Cataloged
+staff.cat.marcedit.authority_see_also=See also: %1$s
+staff.cat.marcedit.authority_see_from=See from: %1$s
 staff.cat.marcedit.help.add_row=Add Row: CTRL+Enter
 staff.cat.marcedit.help.insert_row=Insert Row: CTRL+Shift+Enter
 staff.cat.marcedit.help.copy_row_up=Copy Current Row Above: CTRL+Up