diff options
-rw-r--r-- | Bugzilla/Search.pm | 125 | ||||
-rwxr-xr-x | buglist.cgi | 2 | ||||
-rw-r--r-- | skins/standard/buglist.css | 10 | ||||
-rw-r--r-- | template/en/default/global/field-descs.none.tmpl | 28 | ||||
-rw-r--r-- | template/en/default/list/list.html.tmpl | 27 | ||||
-rw-r--r-- | template/en/default/search/boolean-charts.html.tmpl | 58 | ||||
-rw-r--r-- | template/en/default/search/form.html.tmpl | 62 | ||||
-rw-r--r-- | template/en/default/search/type-select.html.tmpl | 29 |
8 files changed, 229 insertions, 112 deletions
diff --git a/Bugzilla/Search.pm b/Bugzilla/Search.pm index 557af6646..c1593ccc4 100644 --- a/Bugzilla/Search.pm +++ b/Bugzilla/Search.pm @@ -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 { diff --git a/buglist.cgi b/buglist.cgi index f83f957fc..037edae70 100755 --- a/buglist.cgi +++ b/buglist.cgi @@ -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 diff --git a/skins/standard/buglist.css b/skins/standard/buglist.css index ca37dc763..fa50bcb2d 100644 --- a/skins/standard/buglist.css +++ b/skins/standard/buglist.css @@ -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 { } diff --git a/template/en/default/global/field-descs.none.tmpl b/template/en/default/global/field-descs.none.tmpl index 7d89bd5c2..324edb592 100644 --- a/template/en/default/global/field-descs.none.tmpl +++ b/template/en/default/global/field-descs.none.tmpl @@ -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", diff --git a/template/en/default/list/list.html.tmpl b/template/en/default/list/list.html.tmpl index 8d67e6c41..467e4dfc7 100644 --- a/template/en/default/list/list.html.tmpl +++ b/template/en/default/list/list.html.tmpl @@ -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> [%############################################################################%] diff --git a/template/en/default/search/boolean-charts.html.tmpl b/template/en/default/search/boolean-charts.html.tmpl index 97a10d4ab..db21be681 100644 --- a/template/en/default/search/boolean-charts.html.tmpl +++ b/template/en/default/search/boolean-charts.html.tmpl @@ -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 %]"> diff --git a/template/en/default/search/form.html.tmpl b/template/en/default/search/form.html.tmpl index 05b52dca4..46df426c1 100644 --- a/template/en/default/search/form.html.tmpl +++ b/template/en/default/search/form.html.tmpl @@ -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 <u>C</u>omment", + { name => "longdesc", description => "A <u>C</u>omment", accesskey => 'c' }, { name => "bug_file_loc", description => "The <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" diff --git a/template/en/default/search/type-select.html.tmpl b/template/en/default/search/type-select.html.tmpl new file mode 100644 index 000000000..e74cc3cd3 --- /dev/null +++ b/template/en/default/search/type-select.html.tmpl @@ -0,0 +1,29 @@ +[%# 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> |