From 65d75763b90b9485b52f15e2938951ad0fbfaa21 Mon Sep 17 00:00:00 2001 From: "mkanat%bugzilla.org" <> Date: Thu, 29 Oct 2009 04:46:15 +0000 Subject: Bug 524234: When there are no search results, include helpful links Patch by Max Kanat-Alexander r=dkl, a=mkanat --- Bugzilla/User.pm | 23 +++++++++++------ buglist.cgi | 45 +++++++++++++++++++++------------ skins/standard/buglist.css | 5 ++++ template/en/default/list/list.html.tmpl | 43 ++++++++++++++++++++++++------- 4 files changed, 83 insertions(+), 33 deletions(-) diff --git a/Bugzilla/User.pm b/Bugzilla/User.pm index 7057ec90a..9cb53fe34 100644 --- a/Bugzilla/User.pm +++ b/Bugzilla/User.pm @@ -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."; diff --git a/buglist.cgi b/buglist.cgi index 44fe1f075..60713b035 100755 --- a/buglist.cgi +++ b/buglist.cgi @@ -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 })]; + } } } diff --git a/skins/standard/buglist.css b/skins/standard/buglist.css index c9f309ccb..00614a6cf 100644 --- a/skins/standard/buglist.css +++ b/skins/standard/buglist.css @@ -28,6 +28,11 @@ margin-right: 2em; } +.zero_results, .zero_result_links { + font-size: 120%; + font-weight: bold; +} + .bz_id_column { } diff --git a/template/en/default/list/list.html.tmpl b/template/en/default/list/list.html.tmpl index 7c372f1f4..a3e3a767a 100644 --- a/template/en/default/list/list.html.tmpl +++ b/template/en/default/list/list.html.tmpl @@ -142,7 +142,7 @@ [% IF bugs.size == 0 %] - [% terms.zeroSearchResults %]. + [% terms.zeroSearchResults %]. [% ELSIF bugs.size == 1 %] One [% terms.bug %] found. [% ELSE %] @@ -150,6 +150,18 @@ [% END %] +[% IF bugs.size == 0 %] + +[% END %] +
[%############################################################################%] @@ -226,11 +238,7 @@ [% END %] - [% editqueryname = searchname OR defaultsavename OR '' %] - Edit Search + Edit Search [% IF searchtype == "saved" %] @@ -259,10 +267,9 @@ -[% IF cgi.param('product').size == 1 && cgi.param('product') != "" %] +[% IF one_product.defined %]

- File - a new [% terms.bug %] in the "[% cgi.param('product') FILTER html %]" product + [% PROCESS enter_bug_link %]

[% END %] @@ -271,3 +278,21 @@ [%############################################################################%] [% PROCESS global/footer.html.tmpl %] + +[% BLOCK edit_search_url %] + [% editqueryname = searchname OR defaultsavename OR '' %] + query.cgi?[% urlquerypart FILTER html %] + [%- IF editqueryname != '' %]&known_name= + [%- editqueryname FILTER url_quote %] + [% END %] +[% END %] + +[% BLOCK enter_bug_link %] + File + a new [% terms.bug %] + [% IF one_product.defined %] + in the "[% one_product.name FILTER html %]" product + [% END %] +[% END %] -- cgit v1.2.3-24-g4f1b