Commit cce0280b authored by mkanat%bugzilla.org's avatar mkanat%bugzilla.org

Bug 463002 - Show a description of what you searched for, at the top of buglist.cgi

Patch By Max Kanat-Alexander <mkanat@bugzilla.org> r=bbaetz, a=mkanat
parent 33429813
......@@ -88,10 +88,6 @@ sub init {
@inputorder = @$orderref if $orderref;
my @orderby;
my $debug = 0;
my @debugdata;
if ($params->param('debug')) { $debug = 1; }
my @fields;
my @supptables;
my @wherepart;
......@@ -306,8 +302,22 @@ sub init {
my $sql_chvalue = $chvalue ne '' ? $dbh->quote($chvalue) : '';
trick_taint($sql_chvalue);
if(!@chfield) {
push(@wherepart, "bugs.delta_ts >= $sql_chfrom") if ($sql_chfrom);
push(@wherepart, "bugs.delta_ts <= $sql_chto") if ($sql_chto);
if ($sql_chfrom) {
my $term = "bugs.delta_ts >= $sql_chfrom";
push(@wherepart, $term);
$self->search_description({
field => 'delta_ts', type => 'greaterthaneq',
value => $chfieldfrom, term => $term,
});
}
if ($sql_chto) {
my $term = "bugs.delta_ts <= $sql_chto";
push(@wherepart, $term);
$self->search_description({
field => 'delta_ts', type => 'lessthaneq',
value => $chfieldto, term => $term,
});
}
} else {
my $bug_creation_clause;
my @list;
......@@ -317,8 +327,22 @@ sub init {
# Treat [Bug creation] differently because we need to look
# at bugs.creation_ts rather than the bugs_activity table.
my @l;
push(@l, "bugs.creation_ts >= $sql_chfrom") if($sql_chfrom);
push(@l, "bugs.creation_ts <= $sql_chto") if($sql_chto);
if ($sql_chfrom) {
my $term = "bugs.creation_ts >= $sql_chfrom";
push(@l, $term);
$self->search_description({
field => 'creation_ts', type => 'greaterthaneq',
value => $chfieldfrom, term => $term,
});
}
if ($sql_chto) {
my $term = "bugs.creation_ts <= $sql_chto";
push(@l, $term);
$self->search_description({
field => 'creation_ts', type => 'lessthaneq',
value => $chfieldto, term => $term,
});
}
$bug_creation_clause = "(" . join(' AND ', @l) . ")";
} else {
push(@actlist, get_field_id($f));
......@@ -330,18 +354,39 @@ sub init {
if(@actlist) {
my $extra = " actcheck.bug_id = bugs.bug_id";
push(@list, "(actcheck.bug_when IS NOT NULL)");
if($sql_chfrom) {
$extra .= " AND actcheck.bug_when >= $sql_chfrom";
}
if($sql_chto) {
$extra .= " AND actcheck.bug_when <= $sql_chto";
}
if($sql_chvalue) {
$extra .= " AND actcheck.added = $sql_chvalue";
}
my $from_term = " AND actcheck.bug_when >= $sql_chfrom";
$extra .= $from_term if $sql_chfrom;
my $to_term = " AND actcheck.bug_when <= $sql_chto";
$extra .= $to_term if $sql_chto;
my $value_term = " AND actcheck.added = $sql_chvalue";
$extra .= $value_term if $sql_chvalue;
push(@supptables, "LEFT JOIN bugs_activity AS actcheck " .
"ON $extra AND "
. $dbh->sql_in('actcheck.fieldid', \@actlist));
foreach my $field (@chfield) {
next if $field eq "[Bug creation]";
if ($sql_chvalue) {
$self->search_description({
field => $field, type => 'changedto',
value => $chvalue, term => $value_term,
});
}
if ($sql_chfrom) {
$self->search_description({
field => $field, type => 'changedafter',
value => $chfieldfrom, term => $from_term,
});
}
if ($sql_chvalue) {
$self->search_description({
field => $field, type => 'changedbefore',
value => $chfieldto, term => $to_term,
});
}
}
}
# Now that we're done using @list to determine if there are any
......@@ -367,7 +412,12 @@ sub init {
format => 'YYYY-MM-DD'});
$sql_deadlinefrom = $dbh->quote($deadlinefrom);
trick_taint($sql_deadlinefrom);
push(@wherepart, "bugs.deadline >= $sql_deadlinefrom");
my $term = "bugs.deadline >= $sql_deadlinefrom";
push(@wherepart, $term);
$self->search_description({
field => 'deadline', type => 'greaterthaneq',
value => $deadlinefrom, term => $term,
});
}
if ($params->param('deadlineto')){
......@@ -377,11 +427,16 @@ sub init {
format => 'YYYY-MM-DD'});
$sql_deadlineto = $dbh->quote($deadlineto);
trick_taint($sql_deadlineto);
push(@wherepart, "bugs.deadline <= $sql_deadlineto");
my $term = "bugs.deadline <= $sql_deadlineto";
push(@wherepart, $term);
$self->search_description({
field => 'deadline', type => 'lessthaneq',
value => $deadlineto, term => $term,
});
}
}
foreach my $f ("short_desc", "long_desc", "bug_file_loc",
foreach my $f ("short_desc", "longdesc", "bug_file_loc",
"status_whiteboard") {
if (defined $params->param($f)) {
my $s = trim($params->param($f));
......@@ -447,6 +502,7 @@ sub init {
"^(?:deadline|creation_ts|delta_ts),(?:lessthan|greaterthan|equals|notequals),(?:-|\\+)?(?:\\d+)(?:[dDwWmMyY])\$" => \&_timestamp_compare,
"^commenter,(?:equals|anyexact),(%\\w+%)" => \&_commenter_exact,
"^commenter," => \&_commenter,
# The _ is allowed for backwards-compatibility with 3.2 and lower.
"^long_?desc," => \&_long_desc,
"^longdescs\.isprivate," => \&_longdescs_isprivate,
"^work_time,changedby" => \&_work_time_changedby,
......@@ -526,12 +582,6 @@ sub init {
$params->param("field$chart-$row-$col", shift(@$ref));
$params->param("type$chart-$row-$col", shift(@$ref));
$params->param("value$chart-$row-$col", shift(@$ref));
if ($debug) {
push(@debugdata, "$row-$col = " .
$params->param("field$chart-$row-$col") . ' | ' .
$params->param("type$chart-$row-$col") . ' | ' .
$params->param("value$chart-$row-$col") . ' *');
}
$col++;
}
......@@ -639,6 +689,7 @@ sub init {
$params->param("field$chart-$row-$col") ;
$col++) {
$f = $params->param("field$chart-$row-$col") || "noop";
my $original_f = $f; # Saved for search_description
$t = $params->param("type$chart-$row-$col") || "noop";
$v = $params->param("value$chart-$row-$col");
$v = "" if !defined $v;
......@@ -665,24 +716,21 @@ sub init {
foreach my $key (@funcnames) {
if ("$f,$t,$rhs" =~ m/$key/) {
my $ref = $funcsbykey{$key};
if ($debug) {
push(@debugdata, "$key ($f / $t / $rhs) =>");
}
$ff = $f;
if ($f !~ /\./) {
$ff = "bugs.$f";
}
$self->$ref(%func_args);
if ($debug) {
push(@debugdata, "$f / $t / $v / " .
($term || "undef") . " *");
}
if ($term) {
last;
}
}
}
if ($term) {
$self->search_description({
field => $original_f, type => $t, value => $v,
term => $term,
});
push(@orlist, $term);
}
else {
......@@ -808,7 +856,6 @@ sub init {
}
$self->{'sql'} = $query;
$self->{'debugdata'} = \@debugdata;
}
###############################################################################
......@@ -911,9 +958,13 @@ sub getSQL {
return $self->{'sql'};
}
sub getDebugData {
my $self = shift;
return $self->{'debugdata'};
sub search_description {
my ($self, $params) = @_;
my $desc = $self->{'search_description'} ||= [];
if ($params) {
push(@$desc, $params);
}
return $self->{'search_description'};
}
sub pronoun {
......
......@@ -992,6 +992,7 @@ my $search = new Bugzilla::Search('fields' => \@selectnames,
'params' => $params,
'order' => \@orderstrings);
my $query = $search->getSQL();
$vars->{'search_description'} = $search->search_description;
if (defined $cgi->param('limit')) {
my $limit = $cgi->param('limit');
......@@ -1019,7 +1020,6 @@ if ($cgi->param('debug')) {
if (Bugzilla->user->in_group('admin')) {
$vars->{'query_explain'} = $dbh->bz_explain($query);
}
$vars->{'debugdata'} = $search->getDebugData();
}
# Time to use server push to display an interim message to the user until
......
......@@ -18,6 +18,16 @@
* Contributor(s): Myk Melez <myk@mozilla.org>
*/
.search_description {
margin: .5em 0;
padding: 0;
}
.search_description li {
list-style-type: none;
display: inline;
margin-right: 2em;
}
.bz_id_column {
}
......
......@@ -99,6 +99,34 @@
[% END %]
[% END %]
[% SET search_descs = {
"noop" => "---",
"equals" => "is equal to",
"notequals" => "is not equal to",
"anyexact" => "is equal to any of the strings",
"substring" => "contains the string",
"casesubstring" => "contains the string (exact case)",
"notsubstring" => "does not contain the string",
"anywordssubstr" => "contains any of the strings",
"allwordssubstr" => "contains all of the strings",
"nowordssubstr" => "contains none of the strings",
"regexp" => "matches regular expression",
"notregexp" => "does not match regular expression",
"lessthan" => "is less than",
"lessthaneq" => "is less than or equal to",
"greaterthan" => "is greater than",
"greaterthaneq" => "is greater than or equal to",
"anywords" => "contains any of the words",
"allwords" => "contains all of the words",
"nowords" => "contains none of the words",
"changedbefore" => "changed before",
"changedafter" => "changed after",
"changedfrom" => "changed from",
"changedto" => "changed to",
"changedby" => "changed by",
"matches" => "matches",
} %]
[% field_types = { ${constants.FIELD_TYPE_UNKNOWN} => "Unknown Type",
${constants.FIELD_TYPE_FREETEXT} => "Free Text",
${constants.FIELD_TYPE_SINGLE_SELECT} => "Drop Down",
......
......@@ -28,7 +28,7 @@
[%# Template Initialization #%]
[%############################################################################%]
[% PROCESS global/variables.none.tmpl %]
[% PROCESS "global/field-descs.none.tmpl" %]
[% title = "$terms.Bug List" %]
[% IF searchname || defaultsavename %]
......@@ -58,11 +58,6 @@
</span>
[% IF debug %]
<p class="bz_query_debug">
[% FOREACH debugline = debugdata %]
[% debugline FILTER html %]<br>
[% END %]
</p>
<p class="bz_query">[% query FILTER html %]</p>
[% IF query_explain.defined %]
<pre class="bz_query_explain">[% query_explain FILTER html %]</pre>
......@@ -85,6 +80,26 @@
</h2>
[% END %]
[% SET shown_types = [
'notequal', 'regexp', 'notregexp', 'lessthan', 'lessthaneq',
'greaterthan', 'greaterthaneq', 'changedbefore', 'changedafter',
'changedfrom', 'changedto', 'changedby',
] %]
<ul class="search_description">
[% FOREACH desc_item = search_description %]
<li>
<strong>[% field_descs.${desc_item.field} FILTER html %]:</strong>
[% IF shown_types.contains(desc_item.type) || debug %]
([% search_descs.${desc_item.type} FILTER html %])
[% END %]
[%+ desc_item.value FILTER html %]
[% IF debug %]
(<code>[% desc_item.term FILTER html %]</code>)
[% END %]
</li>
[% END %]
</ul>
<hr>
[%############################################################################%]
......
......@@ -17,31 +17,34 @@
#
# Contributor(s): Gervase Markham <gerv@gerv.net>
#%]
[% PROCESS "global/field-descs.none.tmpl" %]
[% types = [
{ name => "noop", description => "---" },
{ name => "equals", description => "is equal to" },
{ name => "notequals", description => "is not equal to" },
{ name => "anyexact", description => "is equal to any of the strings" },
{ name => "substring", description => "contains the string" },
{ name => "casesubstring", description => "contains the string (exact case)" },
{ name => "notsubstring", description => "does not contain the string" },
{ name => "anywordssubstr", description => "contains any of the strings" },
{ name => "allwordssubstr", description => "contains all of the strings" },
{ name => "nowordssubstr", description => "contains none of the strings" },
{ name => "regexp", description => "contains regexp" },
{ name => "notregexp", description => "does not contain regexp" },
{ name => "lessthan", description => "is less than" },
{ name => "greaterthan", description => "is greater than" },
{ name => "anywords", description => "contains any of the words" },
{ name => "allwords", description => "contains all of the words" },
{ name => "nowords", description => "contains none of the words" },
{ name => "changedbefore", description => "changed before" },
{ name => "changedafter", description => "changed after" },
{ name => "changedfrom", description => "changed from" },
{ name => "changedto", description => "changed to" },
{ name => "changedby", description => "changed by" },
{ name => "matches", description => "matches" } ] %]
"noop",
"equals",
"notequals",
"anyexact",
"substring",
"casesubstring",
"notsubstring",
"anywordssubstr",
"allwordssubstr",
"nowordssubstr",
"regexp",
"notregexp",
"lessthan",
"greaterthan",
"anywords",
"allwords",
"nowords",
"changedbefore",
"changedafter",
"changedfrom",
"changedto",
"changedby",
"matches",
] %]
<p>
<strong>
......@@ -80,12 +83,9 @@
[% END %]
</select>
<select name="[% "type${chartnum}-${rownum}-${colnum}" %]">
[% FOREACH type = types %]
<option value="[% type.name %]"
[%- " selected" IF type.name == col.type %]>[% type.description %]</option>
[% END %]
</select>
[% INCLUDE "search/type-select.html.tmpl"
name = "type${chartnum}-${rownum}-${colnum}",
types = types, selected = col.type %]
<input name="[% "value${chartnum}-${rownum}-${colnum}" %]"
value="[% col.value FILTER html %]">
......
......@@ -20,6 +20,8 @@
# Gervase Markham <gerv@gerv.net>
#%]
[% PROCESS "global/field-descs.none.tmpl" %]
<script type="text/javascript">
var first_load = true; [%# is this the first time we load the page? %]
......@@ -103,20 +105,16 @@ function doOnSelectProduct(selectmode) {
</script>
[% PROCESS global/variables.none.tmpl %]
[% query_variants = [
{ value => "allwordssubstr", description => "contains all of the words/strings" },
{ value => "anywordssubstr", description => "contains any of the words/strings" },
{ value => "substring", description => "contains the string" },
{ value => "casesubstring", description => "contains the string (exact case)" },
{ value => "allwords", description => "contains all of the words" },
{ value => "anywords", description => "contains any of the words" },
{ value => "regexp", description => "matches the regexp" },
{ value => "notregexp", description => "doesn't match the regexp" } ] %]
[% PROCESS "global/field-descs.none.tmpl" %]
[% query_types = [
"allwordssubstr",
"anywordssubstr",
"substring",
"casesubstring",
"allwords",
"anywords",
"regexp",
"notregexp",
] %]
[%# If we resubmit to ourselves, we need to know if we are using a format. %]
[% thisformat = query_format != '' ? query_format : format %]
......@@ -130,12 +128,9 @@ function doOnSelectProduct(selectmode) {
<label for="short_desc" accesskey="s"><u>S</u>ummary</label>:
</th>
<td>
<select name="short_desc_type">
[% FOREACH qv = query_variants %]
<option value="[% qv.value %]"
[% " selected" IF default.short_desc_type.0 == qv.value %]>[% qv.description %]</option>
[% END %]
</select>
[% INCLUDE "search/type-select.html.tmpl"
name = "short_desc_type",
types = query_types, selected = default.short_desc_type.0 %]
</td>
<td>
<input name="short_desc" id="short_desc" size="40"
......@@ -265,7 +260,7 @@ function doOnSelectProduct(selectmode) {
[%# *** Comment URL Whiteboard Keywords *** %]
[% FOREACH field = [
{ name => "long_desc", description => "A&nbsp;<u>C</u>omment",
{ name => "longdesc", description => "A&nbsp;<u>C</u>omment",
accesskey => 'c' },
{ name => "bug_file_loc", description => "The&nbsp;<u>U</u>RL",
accesskey => 'u' },
......@@ -278,13 +273,9 @@ function doOnSelectProduct(selectmode) {
<label for="[% field.name %]" accesskey="[% field.accesskey %]">[% field.description %]</label>:
</th>
<td>
<select name="[% field.name %]_type">
[% FOREACH qv = query_variants %]
[% type = "${field.name}_type" %]
<option value="[% qv.value %]"
[% " selected" IF default.$type.0 == qv.value %]>[% qv.description %]</option>
[% END %]
</select>
[% INCLUDE "search/type-select.html.tmpl"
name = field.name _ "_type",
types = query_types, selected = default.$type.0 %]
</td>
<td><input name="[% field.name %]" id="[% field.name %]" size="40"
value="[% default.${field.name}.0 FILTER html %]">
......@@ -300,17 +291,10 @@ function doOnSelectProduct(selectmode) {
<label for="keywords" accesskey="k"><a href="describekeywords.cgi"><u>K</u>eywords</a></label>:
</th>
<td>
<select name="keywords_type">
[% FOREACH qv = [
{ name => "allwords", description => "contains all of the keywords" },
{ name => "anywords", description => "contains any of the keywords" },
{ name => "nowords", description => "contains none of the keywords" } ] %]
<option value="[% qv.name %]"
[% " selected" IF default.keywords_type.0 == qv.name %]>
[% qv.description %]</option>
[% END %]
</select>
[% INCLUDE "search/type-select.html.tmpl"
name = "keywords_type",
types = ['allwords', 'anywords', 'nowords'],
selected = default.keywords_type.0 %]
</td>
<td>
<input name="keywords" id="keywords" size="40"
......
[%# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is the Bugzilla Bug Tracking System.
#
# The Initial Developer of the Original Code is the San Jose State
# University Foundation. Portions created by the Initial Developer are
# Copyright (C) 2008 the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Max Kanat-Alexander <mkanat@bugzilla.org>
#%]
[% PROCESS "global/field-descs.none.tmpl" %]
<select name="[% name FILTER html %]">
[% FOREACH type = types %]
<option value="[% type FILTER html %]"
[%- ' selected="selected"' IF type == selected %]>
[%- search_descs.$type %]</option>
[% END %]
</select>
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