Commit 65d75763 authored by mkanat%bugzilla.org's avatar mkanat%bugzilla.org

Bug 524234: When there are no search results, include helpful links

Patch by Max Kanat-Alexander <mkanat@bugzilla.org> r=dkl, a=mkanat
parent c51e34ce
...@@ -712,17 +712,19 @@ sub get_selectable_classifications { ...@@ -712,17 +712,19 @@ sub get_selectable_classifications {
} }
sub can_enter_product { sub can_enter_product {
my ($self, $product_name, $warn) = @_; my ($self, $input, $warn) = @_;
my $dbh = Bugzilla->dbh; my $dbh = Bugzilla->dbh;
if (!defined($product_name)) { if (!defined $input) {
return unless $warn == THROW_ERROR; return unless $warn == THROW_ERROR;
ThrowUserError('no_products'); ThrowUserError('no_products');
} }
my $product = new Bugzilla::Product({name => $product_name});
my $product = blessed($input) ? $input
: new Bugzilla::Product({ name => $input });
my $can_enter = 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; return 1 if $can_enter;
...@@ -731,21 +733,26 @@ sub can_enter_product { ...@@ -731,21 +733,26 @@ sub can_enter_product {
# Check why access was denied. These checks are slow, # Check why access was denied. These checks are slow,
# but that's fine, because they only happen if we fail. # 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... # The product could not exist or you could be denied...
if (!$product || !$product->user_has_access($self)) { 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... # It could be closed for bug entry...
elsif (!$product->is_active) { elsif (!$product->is_active) {
ThrowUserError('product_disabled', {product => $product}); ThrowUserError('product_disabled', { product => $product });
} }
# It could have no components... # It could have no components...
elsif (!@{$product->components}) { elsif (!@{$product->components}) {
ThrowUserError('missing_component', {product => $product}); ThrowUserError('missing_component', { product => $product });
} }
# It could have no versions... # It could have no versions...
elsif (!@{$product->versions}) { elsif (!@{$product->versions}) {
ThrowUserError ('missing_version', {product => $product}); ThrowUserError ('missing_version', { product => $product });
} }
die "can_enter_product reached an unreachable location."; die "can_enter_product reached an unreachable location.";
......
...@@ -691,12 +691,7 @@ if (grep('relevance', @displaycolumns) && !$fulltext) { ...@@ -691,12 +691,7 @@ if (grep('relevance', @displaycolumns) && !$fulltext) {
# Severity, priority, resolution and status are required for buglist # Severity, priority, resolution and status are required for buglist
# CSS classes. # CSS classes.
my @selectcolumns = ("bug_id", "bug_severity", "priority", "bug_status", my @selectcolumns = ("bug_id", "bug_severity", "priority", "bug_status",
"resolution"); "resolution", "product");
# if using classification, we also need to look in product.classification_id
if (Bugzilla->params->{"useclassification"}) {
push (@selectcolumns,"product");
}
# remaining and actual_time are required for percentage_complete calculation: # remaining and actual_time are required for percentage_complete calculation:
if (lsearch(\@displaycolumns, "percentage_complete") >= 0) { if (lsearch(\@displaycolumns, "percentage_complete") >= 0) {
...@@ -721,11 +716,10 @@ foreach my $col (@displaycolumns) { ...@@ -721,11 +716,10 @@ foreach my $col (@displaycolumns) {
push (@selectcolumns, $col) if !grep($_ eq $col, @selectcolumns); push (@selectcolumns, $col) if !grep($_ eq $col, @selectcolumns);
} }
# If the user is editing multiple bugs, we also make sure to select the product # If the user is editing multiple bugs, we also make sure to select the
# and status because the values of those fields determine what options the user # status, because the values of that field determines what options the user
# has for modifying the bugs. # has for modifying the bugs.
if ($dotweak) { if ($dotweak) {
push(@selectcolumns, "product") if !grep($_ eq 'product', @selectcolumns);
push(@selectcolumns, "bug_status") if !grep($_ eq 'bug_status', @selectcolumns); push(@selectcolumns, "bug_status") if !grep($_ eq 'bug_status', @selectcolumns);
} }
...@@ -1092,6 +1086,25 @@ $vars->{'splitheader'} = $cgi->cookie('SPLITHEADER') ? 1 : 0; ...@@ -1092,6 +1086,25 @@ $vars->{'splitheader'} = $cgi->cookie('SPLITHEADER') ? 1 : 0;
$vars->{'quip'} = GetQuip(); $vars->{'quip'} = GetQuip();
$vars->{'currenttime'} = localtime(time()); $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. # The following variables are used when the user is making changes to multiple bugs.
if ($dotweak && scalar @bugs) { if ($dotweak && scalar @bugs) {
if (!$vars->{'caneditbugs'}) { if (!$vars->{'caneditbugs'}) {
...@@ -1143,19 +1156,19 @@ if ($dotweak && scalar @bugs) { ...@@ -1143,19 +1156,19 @@ if ($dotweak && scalar @bugs) {
$vars->{'new_bug_statuses'} = Bugzilla::Status->new_from_list($bug_status_ids); $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. # The groups the user belongs to and which are editable for the given buglist.
my @products = keys %$bugproducts;
$vars->{'groups'} = GetGroups(\@products); $vars->{'groups'} = GetGroups(\@products);
# If all bugs being changed are in the same product, the user can change # 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 # 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 # versions for the product (if there is only one product on the list of
# products), and a list of components for the product. # products), and a list of components for the product.
if (scalar(@products) == 1) { if ($one_product) {
my $product = new Bugzilla::Product({name => $products[0]}); $vars->{'versions'} = [map($_->name ,@{ $one_product->versions })];
$vars->{'versions'} = [map($_->name ,@{$product->versions})]; $vars->{'components'} = [map($_->name, @{ $one_product->components })];
$vars->{'components'} = [map($_->name, @{$product->components})]; if (Bugzilla->params->{'usetargetmilestone'}) {
$vars->{'targetmilestones'} = [map($_->name, @{$product->milestones})] $vars->{'targetmilestones'} = [map($_->name,
if Bugzilla->params->{'usetargetmilestone'}; @{ $one_product->milestones })];
}
} }
} }
......
...@@ -28,6 +28,11 @@ ...@@ -28,6 +28,11 @@
margin-right: 2em; margin-right: 2em;
} }
.zero_results, .zero_result_links {
font-size: 120%;
font-weight: bold;
}
.bz_id_column { .bz_id_column {
} }
......
...@@ -142,7 +142,7 @@ ...@@ -142,7 +142,7 @@
<span class="bz_result_count"> <span class="bz_result_count">
[% IF bugs.size == 0 %] [% IF bugs.size == 0 %]
[% terms.zeroSearchResults %]. <span class="zero_results">[% terms.zeroSearchResults %].</span>
[% ELSIF bugs.size == 1 %] [% ELSIF bugs.size == 1 %]
One [% terms.bug %] found. One [% terms.bug %] found.
[% ELSE %] [% ELSE %]
...@@ -150,6 +150,18 @@ ...@@ -150,6 +150,18 @@
[% END %] [% END %]
</span> </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> <br>
[%############################################################################%] [%############################################################################%]
...@@ -226,11 +238,7 @@ ...@@ -226,11 +238,7 @@
[% END %] [% END %]
<td valign="middle" class="bz_query_edit"> <td valign="middle" class="bz_query_edit">
[% editqueryname = searchname OR defaultsavename OR '' %] <a href="[% PROCESS edit_search_url %]">Edit&nbsp;Search</a>
<a href="query.cgi?[% urlquerypart FILTER html %]
[% IF editqueryname != '' %]&amp;known_name=
[% editqueryname FILTER url_quote %]
[% END %]">Edit&nbsp;Search</a>
</td> </td>
[% IF searchtype == "saved" %] [% IF searchtype == "saved" %]
...@@ -259,10 +267,9 @@ ...@@ -259,10 +267,9 @@
</tr> </tr>
</table> </table>
[% IF cgi.param('product').size == 1 && cgi.param('product') != "" %] [% IF one_product.defined %]
<p class="bz_query_single_product"> <p class="bz_query_single_product">
<a href="enter_bug.cgi?product=[% cgi.param('product') FILTER url_quote %]">File [% PROCESS enter_bug_link %]
a new [% terms.bug %] in the "[% cgi.param('product') FILTER html %]" product</a>
</p> </p>
[% END %] [% END %]
...@@ -271,3 +278,21 @@ ...@@ -271,3 +278,21 @@
[%############################################################################%] [%############################################################################%]
[% PROCESS global/footer.html.tmpl %] [% 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 %]
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment