]> git.ipfire.org Git - thirdparty/bugzilla.git/commitdiff
Bug 524234: When there are no search results, include helpful links
authormkanat%bugzilla.org <>
Thu, 29 Oct 2009 04:46:15 +0000 (04:46 +0000)
committermkanat%bugzilla.org <>
Thu, 29 Oct 2009 04:46:15 +0000 (04:46 +0000)
Patch by Max Kanat-Alexander <mkanat@bugzilla.org> r=dkl, a=mkanat

Bugzilla/User.pm
buglist.cgi
skins/standard/buglist.css
template/en/default/list/list.html.tmpl

index 7057ec90aa8ede14ab261537059fbeaba7ee32f6..9cb53fe346a1383debddd6959ec03c5c00d80e1b 100644 (file)
@@ -712,17 +712,19 @@ sub get_selectable_classifications {
 }
 
 sub can_enter_product {
-    my ($self, $product_name, $warn) = @_;
+    my ($self, $input, $warn) = @_;
     my $dbh = Bugzilla->dbh;
 
-    if (!defined($product_name)) {
+    if (!defined $input) {
         return unless $warn == THROW_ERROR;
         ThrowUserError('no_products');
     }
-    my $product = new Bugzilla::Product({name => $product_name});
 
+    my $product = blessed($input) ? $input 
+                                  : new Bugzilla::Product({ name => $input });
     my $can_enter =
-      $product && grep($_->name eq $product->name, @{$self->get_enterable_products});
+      $product && grep($_->name eq $product->name,
+                       @{ $self->get_enterable_products });
 
     return 1 if $can_enter;
 
@@ -731,21 +733,26 @@ sub can_enter_product {
     # Check why access was denied. These checks are slow,
     # but that's fine, because they only happen if we fail.
 
+    # We don't just use $product->name for error messages, because if it
+    # changes case from $input, then that's a clue that the product does
+    # exist but is hidden.
+    my $name = blessed($input) ? $input->name : $input;
+
     # The product could not exist or you could be denied...
     if (!$product || !$product->user_has_access($self)) {
-        ThrowUserError('entry_access_denied', {product => $product_name});
+        ThrowUserError('entry_access_denied', { product => $name });
     }
     # It could be closed for bug entry...
     elsif (!$product->is_active) {
-        ThrowUserError('product_disabled', {product => $product});
+        ThrowUserError('product_disabled', { product => $product });
     }
     # It could have no components...
     elsif (!@{$product->components}) {
-        ThrowUserError('missing_component', {product => $product});
+        ThrowUserError('missing_component', { product => $product });
     }
     # It could have no versions...
     elsif (!@{$product->versions}) {
-        ThrowUserError ('missing_version', {product => $product});
+        ThrowUserError ('missing_version', { product => $product });
     }
 
     die "can_enter_product reached an unreachable location.";
index 44fe1f075d585f47b96c6cd3a627a15a99e154dc..60713b0358bbbe9dc4894f33677d266fda4e1033 100755 (executable)
@@ -691,12 +691,7 @@ if (grep('relevance', @displaycolumns) && !$fulltext) {
 # Severity, priority, resolution and status are required for buglist
 # CSS classes.
 my @selectcolumns = ("bug_id", "bug_severity", "priority", "bug_status",
-                     "resolution");
-
-# if using classification, we also need to look in product.classification_id
-if (Bugzilla->params->{"useclassification"}) {
-    push (@selectcolumns,"product");
-}
+                     "resolution", "product");
 
 # remaining and actual_time are required for percentage_complete calculation:
 if (lsearch(\@displaycolumns, "percentage_complete") >= 0) {
@@ -721,11 +716,10 @@ foreach my $col (@displaycolumns) {
     push (@selectcolumns, $col) if !grep($_ eq $col, @selectcolumns);
 }
 
-# If the user is editing multiple bugs, we also make sure to select the product
-# and status because the values of those fields determine what options the user
+# If the user is editing multiple bugs, we also make sure to select the 
+# status, because the values of that field determines what options the user
 # has for modifying the bugs.
 if ($dotweak) {
-    push(@selectcolumns, "product") if !grep($_ eq 'product', @selectcolumns);
     push(@selectcolumns, "bug_status") if !grep($_ eq 'bug_status', @selectcolumns);
 }
 
@@ -1092,6 +1086,25 @@ $vars->{'splitheader'} = $cgi->cookie('SPLITHEADER') ? 1 : 0;
 $vars->{'quip'} = GetQuip();
 $vars->{'currenttime'} = localtime(time());
 
+# See if there's only one product in all the results (or only one product
+# that we searched for), which allows us to provide more helpful links.
+my @products = keys %$bugproducts;
+my $one_product;
+if (scalar(@products) == 1) {
+    $one_product = new Bugzilla::Product({ name => $products[0] });
+}
+# This is used in the "Zarroo Boogs" case.
+elsif (my @product_input = $cgi->param('product')) {
+    if (scalar(@product_input) == 1 and $product_input[0] ne '') {
+        $one_product = new Bugzilla::Product({ name => $cgi->param('product') });
+    }
+}
+# We only want the template to use it if the user can actually 
+# enter bugs against it.
+if (Bugzilla->user->can_enter_product($one_product)) {
+    $vars->{'one_product'} = $one_product;
+}
+
 # The following variables are used when the user is making changes to multiple bugs.
 if ($dotweak && scalar @bugs) {
     if (!$vars->{'caneditbugs'}) {
@@ -1143,19 +1156,19 @@ if ($dotweak && scalar @bugs) {
     $vars->{'new_bug_statuses'} = Bugzilla::Status->new_from_list($bug_status_ids);
 
     # The groups the user belongs to and which are editable for the given buglist.
-    my @products = keys %$bugproducts;
     $vars->{'groups'} = GetGroups(\@products);
 
     # If all bugs being changed are in the same product, the user can change
     # their version and component, so generate a list of products, a list of
     # versions for the product (if there is only one product on the list of
     # products), and a list of components for the product.
-    if (scalar(@products) == 1) {
-        my $product = new Bugzilla::Product({name => $products[0]});
-        $vars->{'versions'} = [map($_->name ,@{$product->versions})];
-        $vars->{'components'} = [map($_->name, @{$product->components})];
-        $vars->{'targetmilestones'} = [map($_->name, @{$product->milestones})]
-            if Bugzilla->params->{'usetargetmilestone'};
+    if ($one_product) {
+        $vars->{'versions'} = [map($_->name ,@{ $one_product->versions })];
+        $vars->{'components'} = [map($_->name, @{ $one_product->components })];
+        if (Bugzilla->params->{'usetargetmilestone'}) {
+            $vars->{'targetmilestones'} = [map($_->name, 
+                                               @{ $one_product->milestones })];
+        }
     }
 }
 
index c9f309ccbcb26640fb919e898660d6d61e0cb8cb..00614a6cf3a9fd61e6195f5ac1291dda4137b709 100644 (file)
   margin-right: 2em;
 }
 
+.zero_results, .zero_result_links {
+  font-size: 120%;
+  font-weight: bold;
+}
+
 .bz_id_column {
 }
 
index 7c372f1f4c1575225eb331b77ff3dc3dc64be3bf..a3e3a767adf0acd86fa8c9b57fd65afbe3605295 100644 (file)
 
 <span class="bz_result_count">
   [% IF bugs.size == 0 %]
-    [% terms.zeroSearchResults %].
+    <span class="zero_results">[% terms.zeroSearchResults %].</span>
   [% ELSIF bugs.size == 1 %]
     One [% terms.bug %] found.
   [% ELSE %]
   [% END %]
 </span>
 
+[% IF bugs.size == 0 %]
+  <ul class="zero_result_links">
+    <li>[% PROCESS enter_bug_link %]</li>
+    [% IF one_product.defined %]
+      <li><a href="enter_bug.cgi">File a new [% terms.bug %] in a
+        different product</a></li>
+    [% END %]
+    <li><a href="[% PROCESS edit_search_url %]">Edit this search</a></li>
+    <li><a href="query.cgi">Start a new search</a></li>
+  </ul>
+[% END %]
+
 <br>
 
 [%############################################################################%]
     [% END %]
     
     <td valign="middle" class="bz_query_edit">
-      [% editqueryname = searchname OR defaultsavename OR '' %]
-      <a href="query.cgi?[% urlquerypart FILTER html %]
-      [% IF editqueryname != '' %]&amp;known_name=
-        [% editqueryname FILTER url_quote %]
-      [% END %]">Edit&nbsp;Search</a>
+      <a href="[% PROCESS edit_search_url %]">Edit&nbsp;Search</a>
     </td>
       
     [% IF searchtype == "saved" %]
   </tr>
 </table>
 
-[% IF cgi.param('product').size == 1 && cgi.param('product') != "" %]
+[% IF one_product.defined %]
   <p class="bz_query_single_product">
-    <a href="enter_bug.cgi?product=[% cgi.param('product') FILTER url_quote %]">File
-      a new [% terms.bug %] in the "[% cgi.param('product') FILTER html %]" product</a>
+    [% PROCESS enter_bug_link %]
   </p>
 [% END %]
 
 [%############################################################################%]
 
 [% PROCESS global/footer.html.tmpl %]
+
+[% BLOCK edit_search_url %]
+  [% editqueryname = searchname OR defaultsavename OR '' %]
+  query.cgi?[% urlquerypart FILTER html %]
+    [%- IF editqueryname != '' %]&amp;known_name=
+      [%- editqueryname FILTER url_quote %]
+    [% END %]
+[% END %]
+
+[% BLOCK enter_bug_link %]
+  <a href="enter_bug.cgi
+           [%- IF one_product.defined %]?product=
+             [%- one_product.name FILTER url_quote %][% END %]">File
+    a new [% terms.bug %]
+   [% IF one_product.defined %]
+     in the "[% one_product.name FILTER html %]" product
+   [% END %]</a>
+[% END %]