]> git.ipfire.org Git - thirdparty/bugzilla.git/commitdiff
Bug 171437 - Enhancements to generic reporting. Reporting menu, 3D tables, rearranged...
authorgerv%gerv.net <>
Tue, 8 Oct 2002 13:41:17 +0000 (13:41 +0000)
committergerv%gerv.net <>
Tue, 8 Oct 2002 13:41:17 +0000 (13:41 +0000)
CGI.pl
query.cgi
report.cgi
template/en/default/global/useful-links.html.tmpl
template/en/default/global/user-error.html.tmpl
template/en/default/reports/menu.html.tmpl [new file with mode: 0644]
template/en/default/reports/report-table.csv.tmpl [moved from template/en/default/reports/table.csv.tmpl with 58% similarity]
template/en/default/reports/report-table.html.tmpl [new file with mode: 0644]
template/en/default/reports/table.html.tmpl [deleted file]
template/en/default/search/search-report-table.html.tmpl

diff --git a/CGI.pl b/CGI.pl
index 3d6752a5773d49d31b0735f3ce59689446036d77..20f257d6038f558a6f0a8a3e5ca22233d74920b6 100644 (file)
--- a/CGI.pl
+++ b/CGI.pl
@@ -199,6 +199,35 @@ sub ProcessMultipartFormFields {
     }
 }
 
+sub CanonicaliseParams {
+    my ($buffer, $exclude) = (@_);
+    my %pieces;
+    
+    # Split the buffer up into key/value pairs, and store the non-empty ones
+    my @args = split('&', $buffer);
+        
+    foreach my $arg (@args) {
+        my ($name, $value) = split('=', $arg, 2);
+
+        if ($value) {
+            push(@{$pieces{$name}}, $value);
+        }
+    }
+
+    # Reconstruct the URL by concatenating the sorted param=value pairs
+    my @parameters;
+    foreach my $key (sort keys %pieces) {
+        # Leave this key out if it's in the exclude list
+        next if lsearch($exclude, $key) != -1; 
+        
+        foreach my $value (@{$pieces{$key}}) {
+            push(@parameters, "$key=$value");
+        }
+    }
+    
+    return join("&", @parameters);
+}
+
 # check and see if a given field exists, is non-empty, and is set to a 
 # legal value.  assume a browser bug and abort appropriately if not.
 # if $legalsRef is not passed, just check to make sure the value exists and 
index 4bda141c35eb78fbc9d6adfedd4abe1732ac838f..1aa17b723eff905cdd28d470b5f23888a2fdbcbd 100755 (executable)
--- a/query.cgi
+++ b/query.cgi
@@ -131,7 +131,7 @@ sub PrefillForm {
                       "bug_file_loc_type", "status_whiteboard",
                       "status_whiteboard_type", "bug_id",
                       "bugidtype", "keywords", "keywords_type",
-                      "x_axis_field", "y_axis_field") 
+                      "x_axis_field", "y_axis_field", "z_axis_field"
     {
         # This is a bit of a hack. The default, empty list has 
         # three entries to accommodate the needs of the email fields -
index 525897771719f850c38df5fc279c4b3f00ccb29b..35055110e9633ec1e16b87cacaadc6d4fd2ec617 100755 (executable)
@@ -37,13 +37,22 @@ GetVersionTable();
 
 quietly_check_login();
 
-# If other report types are added, some of this code can be moved into a sub,
-# and the correct sub chosen based on $::FORM{'type'}.
+if ($::FORM{'action'} ne "plot") {
+    print "Content-Type: text/html\n\n";
+    $template->process("reports/menu.html.tmpl", $vars)
+      || ThrowTemplateError($template->error());
+    exit;
+}
 
 $::FORM{'y_axis_field'} || ThrowCodeError("no_y_axis_defined");
 
+if ($::FORM{'z_axis_field'} && !$::FORM{'x_axis_field'}) {
+    ThrowUserError("z_axis_defined_with_no_x_axis");
+}
+
 my $col_field = $::FORM{'x_axis_field'};
 my $row_field = $::FORM{'y_axis_field'};
+my $tbl_field = $::FORM{'z_axis_field'};
 
 my %columns;
 $columns{'bug_severity'}     = "bugs.bug_severity";        
@@ -61,10 +70,11 @@ $columns{'op_sys'}           = "bugs.op_sys";
 $columns{'votes'}            = "bugs.votes";
 $columns{'keywords'}         = "bugs.keywords";
 $columns{'target_milestone'} = "bugs.target_milestone";
+# One which means "nothing". Any number would do, really. It just gets SELECTed
+# so that we always select 3 items in the query.
+$columns{''}                 = "42217354";
 
-my @axis_fields = ($row_field);
-# The X axis (horizontal) is optional
-push(@axis_fields, $col_field) if $col_field;
+my @axis_fields = ($row_field, $col_field, $tbl_field);
 
 my @selectnames = map($columns{$_}, @axis_fields);
 
@@ -72,59 +82,42 @@ my $search = new Bugzilla::Search('fields' => \@selectnames,
                                   'url' => $::buffer);
 my $query = $search->getSQL();
 
-$query =~ s/DISTINCT//;
 SendSQL($query, $::userid);
 
-# We have a hash for each direction for the totals, and a hash of hashes for 
-# the data itself.
+# We have a hash of hashes for the data itself, and a hash to hold the 
+# row/col/table names.
 my %data;
-my %row_totals;
-my %col_totals;
-my $grand_total;
+my %names;
 
 # Read the bug data and increment the counts.
 while (MoreSQLData()) {
-    my ($row, $col) = FetchSQLData();    
-    $row = "" if !defined($row);
-    $col = "" if !defined($col);
+    my ($row, $col, $tbl) = FetchSQLData();
+    $col = "" if ($col == $columns{''});
+    $tbl = "" if ($tbl == $columns{''});
     
-    $data{$row}{$col}++;    
-    $row_totals{$row}++;    
-    $col_totals{$col}++;    
-    $grand_total++;
+    $data{$tbl}{$col}{$row}++;
+    $names{"col"}{$col}++;
+    $names{"row"}{$row}++;
+    $names{"tbl"}{$tbl}++;
 }
 
-$vars->{'data'} = \%data;
-$vars->{'row_totals'} = \%row_totals;
-$vars->{'col_totals'} = \%col_totals;
-$vars->{'grand_total'} = $grand_total;
-
 # Determine the labels for the rows and columns
-my @row_names = sort(keys(%row_totals));
-my @col_names = sort(keys(%col_totals));
-
-$vars->{'row_names'} = \@row_names;
-$vars->{'col_names'} = \@col_names;
-
-$vars->{'row_field'} = $row_field;
 $vars->{'col_field'} = $col_field;
+$vars->{'row_field'} = $row_field;
+$vars->{'tbl_field'} = $tbl_field;
+$vars->{'names'} = \%names;
+$vars->{'data'} = \%data;
+$vars->{'time'} = time();
 
 $::buffer =~ s/format=[^&]*&?//g;
 
 # Calculate the base query URL for the hyperlinked numbers
-my $buglistbase = $::buffer;
-$buglistbase =~ s/$row_field=[^&]*&?//g;
-$buglistbase =~ s/$col_field=[^&]*&?//g;
-
-$vars->{'buglistbase'} = $buglistbase;
+$vars->{'buglistbase'} = CanonicaliseParams($::buffer, 
+                ["x_axis_field", "y_axis_field", "z_axis_field", @axis_fields]);
 $vars->{'buffer'} = $::buffer;
 
-$::FORM{'type'} =~ s/[^a-zA-Z\-]//g;
-
 # Generate and return the result from the appropriate template.
-my $format = GetFormat("reports/$::FORM{'type'}", 
-                       $::FORM{'format'}, 
-                       $::FORM{'ctype'});
+my $format = GetFormat("reports/report", $::FORM{'format'}, $::FORM{'ctype'});
 print "Content-Type: $format->{'contenttype'}\n\n";
 $template->process("$format->{'template'}", $vars)
   || ThrowTemplateError($template->error());
index 785a9d75eda63895d1cc0b4be144572a2ab91654..07ae8f6feebaaa385bd837ad31e6a64a21703b34 100644 (file)
@@ -49,7 +49,7 @@
         <input type="submit" value="Find"> bug # 
         <input name="id" size="6"> | 
         
-        <a href="reports.cgi">Reports</a> 
+        <a href="report.cgi">Reports</a> 
         
         | <a href="request.cgi">Requests</a>
        
index 1f36f6f1e6a62a4000a79693a5c4923f1795bdef..91ee0174339748cc9d4246d79aea4da66c10158f 100644 (file)
     [% title = "Wrong Token" %]
     That token cannot be used to change your email address.
 
+  [% ELSIF error == "z_axis_defined_with_no_x_axis" %]
+    [% title = "Nonsensical Options" %]
+    You've defined a field for multiple tables without having defined
+    a horizontal axis for those tables.
+
   [% ELSIF error == "zero_length_file" %]
     [% title = "File Is Empty" %]
     The file you are trying to attach is empty!    
diff --git a/template/en/default/reports/menu.html.tmpl b/template/en/default/reports/menu.html.tmpl
new file mode 100644 (file)
index 0000000..d937175
--- /dev/null
@@ -0,0 +1,61 @@
+<!-- 1.0@bugzilla.org -->
+[%# 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 Netscape Communications
+  # Corporation. Portions created by Netscape are
+  # Copyright (C) 1998 Netscape Communications Corporation. All
+  # Rights Reserved.
+  #
+  # Contributor(s): Gervase Markham <gerv@gerv.net>
+  #%]
+
+[%# INTERFACE:
+  # This template has no interface. It's a list of the available report
+  # types in Bugzilla.
+  #%]
+
+[% PROCESS global/header.html.tmpl 
+  title = "Reporting and Charting Kitchen"
+%]
+
+<p>
+  Bugzilla allows you to view and track the state of your bug database in
+  all manner of exciting ways.
+</p>
+
+<h2>Current State</h2>
+
+<ul>
+  <li>
+    <strong><a href="query.cgi">Search</a></strong> - 
+    list sets of bugs.
+  </li>
+  <li>
+    <strong>
+      <a href="query.cgi?format=report-table">Tabular reports</a>
+    </strong> -
+    tables of bug counts in 1, 2 or 3 dimensions, as HTML or CSV.
+  </li>
+</ul>
+
+<h2>Change Over Time</h2>
+
+<ul>
+  <li>
+    <strong><a href="reports.cgi">Charts</a></strong> - 
+    plot the status and/or resolution of bugs against
+    time, for each product in your database.
+  </li>
+</ul>
+
+[% PROCESS global/footer.html.tmpl %]
similarity index 58%
rename from template/en/default/reports/table.csv.tmpl
rename to template/en/default/reports/report-table.csv.tmpl
index 96b0c3971cffa4b1c4a93bf6f58045fd544b15a9..a80a618c8580bd925a543b77a30b52018eb90aba 100644 (file)
 [%# INTERFACE:
   # See report.html.tmpl.
   #%]
-[% row_field FILTER csv -%]
+  
+[% tbl_names = names.tbl.keys.sort %]
+[% col_names = names.col.keys.sort %]
+[% row_names = names.row.keys.sort %]
 
-[% IF col_field -%]
+[% FOREACH tbl = tbl_names %]
+  [% IF tbl_field -%]
+    [% tbl FILTER html %]
+  [% END %]
+
+  [% row_field FILTER csv -%]
+
+  [% IF col_field -%]
  \ [% col_field FILTER csv -%],
-[% FOREACH col = col_names -%]
-[% col FILTER csv -%],
-[% END -%]
-[% ELSE -%]
-,Number of bugs,
-[% END %]
+  [% FOREACH col = col_names -%]
+    [% col FILTER csv -%],
+  [% END -%]
+  [% ELSE -%]
+    [% -%],Number of bugs
+  [% END %]
 
-[% FOREACH row = row_names %]
-[% row FILTER csv -%],
-[% FOREACH col = col_names %]
-[% IF data.$row AND data.$row.$col %][% data.$row.$col -%],[% ELSE %]0,[% END %]
-[% END %]
+  [% FOREACH row = row_names %]
+    [% row FILTER csv -%],
+    [% FOREACH col = col_names %]
+      [% IF data.$tbl AND data.$tbl.$col AND data.$tbl.$col.$row %]
+        [% data.$tbl.$col.$row -%],
+      [% ELSE %]
+        [% -%]0,
+      [% END %]
+    [% END %]
 
+  [% END %]
+  
 [% END %]
diff --git a/template/en/default/reports/report-table.html.tmpl b/template/en/default/reports/report-table.html.tmpl
new file mode 100644 (file)
index 0000000..81ca278
--- /dev/null
@@ -0,0 +1,207 @@
+ <!-- 1.0@bugzilla.org -->
+[%# 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 Netscape Communications
+  # Corporation. Portions created by Netscape are
+  # Copyright (C) 1998 Netscape Communications Corporation. All
+  # Rights Reserved.
+  #
+  # Contributor(s): Gervase Markham <gerv@gerv.net>
+  #                 <rdean@cambianetworks.com>
+  #%]
+
+[%# INTERFACE:
+  # basequery: The base query for this table, in URL form
+  # data: hash of hash of hash of numbers. Bug counts.
+  # names: hash of hash of strings. Names of tables, rows and columns.
+  # col_field: string. Name of the field being plotted as columns.
+  # row_field: string. Name of the field being plotted as rows.
+  # tbl_field: string. Name of the field being plotted as tables.
+  #%]
+
+[% PROCESS "global/field-descs.html.tmpl" %]
+
+[% tbl_field_disp = field_descs.$tbl_field || tbl_field %]
+[% col_field_disp = field_descs.$col_field || col_field %]
+[% row_field_disp = field_descs.$row_field || row_field %]
+
+[% title = BLOCK %]
+  Report: 
+  [% "$tbl_field_disp / " IF tbl_field %]
+  [% "$col_field_disp / " IF col_field %]
+  [% row_field_disp %]
+[% END %]
+
+[% PROCESS global/header.html.tmpl 
+  style = "
+    .t1     { background-color: #ffffff } /* white       */
+    .t2     { background-color: #dfefff } /* light blue  */
+    .t3     { background-color: #dddddd } /* grey        */
+    .t4     { background-color: #c3d3ed } /* darker blue */
+    .ttotal { background-color: #cfffdf } /* light green */
+  "
+%]
+
+<div align="right">
+  [% time2str("%Y-%m-%d %H:%M:%S", time) %]
+</div>
+
+[% tbl_names = names.tbl.keys.sort %]
+[% col_names = names.col.keys.sort %]
+[% row_names = names.row.keys.sort %]
+
+[% total_name = "Total" %]
+
+[% IF tbl_field %]
+  [%# Calculate and set up the Total table %]
+  
+  [% FOREACH tbl = tbl_names %]
+    [% FOREACH row = row_names %]
+      [% FOREACH col = col_names %]
+        [% data.$total_name.$col.$row = 
+           data.$total_name.$col.$row + data.$tbl.$col.$row %]
+      [% END %]
+    [% END %]
+  [% END %]
+  
+  [% tbl_names.push(total_name) %]
+[% END %]
+
+<div align="center">
+
+[% FOREACH tbl = tbl_names %]
+  <table>
+    [% IF tbl_field %]
+      <tr>
+        <td>
+        </td>
+        <td align="center">
+          <h2>[% tbl FILTER html %]</h2>
+        </td>
+      </tr>
+    [% END %]  
+    <tr>
+      <td>
+      </td>
+      <td align="center">
+        <strong>[% col_field_disp FILTER html %]</strong>
+      </td>
+    </tr>
+
+    <tr>
+      <td valign="middle">
+        <strong>[% row_field_disp FILTER html %]</strong>
+      </td>
+      <td>
+
+
+[% classes = [ [ "t1", "t2" ] , [ "t3", "t4" ] ] %]
+[% col_idx = 0 %]
+[% row_idx = 0 %]
+[% grand_total = 0 %]
+
+<table border="1">
+  [% IF col_field %]
+    <tr>
+      <td class="[% classes.$row_idx.$col_idx %]">
+      </td>
+      [% FOREACH col = col_names %]
+        [% col_totals.$col = 0 %]
+        [% NEXT IF col == "" %]
+        
+        [% col_idx = 1 - col_idx %]
+        <td class="[% classes.$row_idx.$col_idx %]">
+          [% col FILTER html %]
+        </td>
+      [% END %]
+      <td class="ttotal">
+        Total
+      </td>
+    </tr>
+  [% END %]
+  
+  [% FOREACH row = row_names %]
+    [% row_total = 0 %]
+    
+    [% row_idx = 1 - row_idx %]
+    <tr>
+      <td class="[% classes.$row_idx.$col_idx %]" align="right">
+        [% row FILTER html %]
+      </td>
+      [% FOREACH col = col_names %]
+        [% row_total = row_total + data.$tbl.$col.$row %]
+        [% col_totals.$col = col_totals.$col + data.$tbl.$col.$row %]
+        [% NEXT IF col == "" %]
+        
+        [% col_idx = 1 - col_idx %]
+        <td class="[% classes.$row_idx.$col_idx %]" align="center">
+          [% IF data.$tbl.$col.$row AND data.$tbl.$col.$row > 0 %]
+            <a href="buglist.cgi?[% buglistbase %]&
+              [% tbl_field FILTER url_quote %]=[% tbl FILTER url_quote %]&amp;
+              [% row_field FILTER url_quote %]=[% row FILTER url_quote %]&amp;
+              [% col_field FILTER url_quote %]=[% col FILTER url_quote %]">
+              [% data.$tbl.$col.$row %]</a>
+          [% ELSE %]
+            .
+          [% END %]
+        </td>
+      [% END %] 
+      <td class="ttotal" align="right">
+        <a href="buglist.cgi?[% buglistbase %]&
+          [% tbl_field FILTER url_quote %]=[% tbl FILTER url_quote %]&amp;
+          [% row_field FILTER url_quote %]=[% row FILTER url_quote %]">
+        [% row_total %]</a>
+        [% grand_total = grand_total + row_total %]
+      </td>
+    </tr>
+  [% END %]
+  
+  <tr>
+    [% row_idx = 1 - row_idx %]
+    <td class="ttotal">
+      Total
+    </td>
+    [% FOREACH col = col_names %]
+      [% NEXT IF col == "" %]
+      
+      <td class="ttotal" align="center">
+        <a href="buglist.cgi?[% buglistbase %]&
+          [% tbl_field FILTER url_quote %]=[% tbl FILTER url_quote %]&amp;
+          [% col_field FILTER url_quote %]=[% col FILTER url_quote %]">
+        [% col_totals.$col %]</a>
+      <strong>
+      </td> 
+    [% END %]
+    <td class="ttotal" align="right">
+      <strong>
+        <a href="buglist.cgi?[% buglistbase %]">[% grand_total %]</a>
+      </strong>
+    </td>
+  </tr>
+</table>
+      
+      
+      </td>
+    </tr>
+  </table>
+    
+  <br>
+
+[% END %]
+  
+  <a href="query.cgi?[% buffer %]&format=report-table">Edit this report</a>
+</div>
+
+<br>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/reports/table.html.tmpl b/template/en/default/reports/table.html.tmpl
deleted file mode 100644 (file)
index d9a04d5..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
- <!-- 1.0@bugzilla.org -->
-[%# 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 Netscape Communications
-  # Corporation. Portions created by Netscape are
-  # Copyright (C) 1998 Netscape Communications Corporation. All
-  # Rights Reserved.
-  #
-  # Contributor(s): Gervase Markham <gerv@gerv.net>
-  #                 <rdean@cambianetworks.com>
-  #%]
-
-[%# INTERFACE:
-  # basequery: The base query for this table, in URL form
-  # row_field: string. The field name for the data in table rows
-  # col_field: string. The field name for the data in table columns
-  # col_names: array of strings. Values for the columns
-  # row_names: array of strings. Values for the rows
-  # col_totals: hash of integers. Totals for the columns, indexed by col_names.
-  # row_totals: hash of integers. Totals for the rows, indexed by row_names.
-  # data: hash of hash of numbers. Bug counts indexed by col_names and 
-  #       row_names values.
-  #%]
-
-[% PROCESS global/header.html.tmpl 
-  title = "Report"
-  onload = "selectProduct(document.forms['queryform']);"
-  style = "
-    .t1     { background-color: #ffffff }
-    .t2     { background-color: #dfefff }
-    .t3     { background-color: #dddddd }
-    .t4     { background-color: #c3d3ed }
-    .ttotal { background-color: #cfffdf }
-  "
-%]
-
-<div align="center">
-  <table>
-    <tr>
-      <td>
-      </td>
-      <td align="center">
-        <strong>[% col_field FILTER html %]</strong>
-      </td>
-    </tr>
-
-    <tr>
-      <td valign="middle">
-        <strong>[% row_field FILTER html %]</strong>
-      </td>
-      <td>
-
-
-[% classes = [ [ "t1", "t2" ] , [ "t3", "t4" ] ] %]
-[% col_idx = 0 %]
-[% row_idx = 0 %]
-
-<table>
-  [% IF col_names %]
-    <tr>
-      <td class="[% classes.$row_idx.$col_idx %]">
-      </td>
-      [% FOREACH col = col_names %]
-        [%# If no col header, skip the col. This makes display look right if
-            there's no defined X axis. Not doing this gives us two cols. %]
-        [% NEXT IF col == "" %] 
-        [% col_idx = 1 - col_idx %]
-        <td class="[% classes.$row_idx.$col_idx %]">
-          [% col FILTER html %]
-        </td>
-      [% END %]
-      <td class="ttotal">
-        Total
-      </td>
-    </tr>
-  [% END %]
-  
-  [% FOREACH row = row_names %]
-    [% row_idx = 1 - row_idx %]
-    <tr>
-      <td class="[% classes.$row_idx.$col_idx %]">
-        [% row FILTER html %]
-      </td>
-      [% FOREACH col = col_names %]
-        [% NEXT IF col == "" %]
-        [% col_idx = 1 - col_idx %]
-        <td class="[% classes.$row_idx.$col_idx %]" align="center">
-          [% IF data.$row.$col AND data.$row.$col > 0 %]
-            <a href="buglist.cgi?[% buglistbase %]&
-              [% row_field FILTER url_quote %]=[% row FILTER url_quote %]&
-              [% col_field FILTER url_quote %]=[% col FILTER url_quote %]">
-              [% data.$row.$col %]</a>
-          [% ELSE %]
-            .
-          [% END %]
-        </td>
-      [% END %] 
-      <td class="ttotal">
-        [% row_totals.$row %]
-      </td>
-    </tr>
-  [% END %]
-  
-  <tr>
-    [% row_idx = 1 - row_idx %]
-    <td class="ttotal">
-      Total
-    </td>
-    [% FOREACH col = col_names %]
-      [% NEXT IF col == "" %]
-      <td class="ttotal" align="center">
-        [% col_totals.$col %]
-      </td> 
-    [% END %]
-    <td class="ttotal">
-      <strong>
-        [% grand_total %]
-      </strong>
-    </td>
-  </tr>
-</table>
-      
-      
-      </td>
-    </tr>
-  </table>
-  
-  <a href="query.cgi?[% buffer %]&format=report-table">Edit this report</a>
-</div>
-
-<br>
-
-[% PROCESS global/footer.html.tmpl %]
index 32f8161354ac03e135aa54cec0be864cdc1eead3..73d542124a534312aa23d399a76c95d8fc30a773 100644 (file)
   onload = "selectProduct(document.forms['reportform']);"
 %]
 
+[% PROCESS "global/field-descs.html.tmpl" %]
+
 <p>
-  Produce a table of bug counts by choosing two fields to plot against each 
-  other, and then refining your set of bugs using the rest of the form.
+  Produce a table of bug counts by choosing one or more fields to plot against
+  each other, and then refining your set of bugs using the rest of the form. If
+  you choose a third axis, it will be represented by multiple tables of data.
 </p>
 
 [% button_name = "Generate Report" %]
 
 <form method="get" action="report.cgi" name="reportform">
 
-<table>
+<table align="center">
   <tr>
-    <th align="center">
-      Vertical Axis
-    </th>
-    <th align="center">
-      Horizontal Axis
-    </th>
-    <th>
-      &nbsp;&nbsp;
-    </th>
-    <th align="center">
-      Format
-    </th>
+    <td>
+    </td>
+    <td align="center">
+      <b>Horizontal Axis:</b>
+      [% PROCESS select sel = { name => 'x_axis_field', noop = 1 } %]
+    </td>
+    <td>&nbsp;&nbsp;</td>
+    <td rowspan="2">
+      <b>Format:</b><br>
+      <input type="radio" name="ctype" value="html" checked>HTML<br>
+      <input type="radio" name="ctype" value="csv">CSV
+    </td>
   </tr>
   
   <tr>
-    <td align="center">
+    <td valign="middle" align="center">
+      <b>Vertical Axis:</b><br>
       [% PROCESS select sel = { name => 'y_axis_field' } %]
     </td>
-    <td align="center">  
-      [% PROCESS select sel = { name => 'x_axis_field', noop = 1 } %]
-    </td>
-    <td>
-      &nbsp;&nbsp;
-    </td>
-    <td>
-      <input type="radio" name="ctype" value="html" checked>HTML
-      <input type="radio" name="ctype" value="csv">CSV
+    <td width="150px" height="150px">
+      <table border="1" width="100%" height="100%">
+        <tr>
+          <td align="center" valign="middle">
+            <b>Multiple Tables:</b><br>
+            [% PROCESS select sel = { name => 'z_axis_field', noop = 1 } %]
+          </td>
+        </tr>
+      </table>
     </td>
   </tr>
-</table>
+</table>  
 
 <hr>
 
@@ -77,7 +81,8 @@
 
 <br>
 <input type="submit" value="[% button_name %]">
-<input type="hidden" name="type" value="table">
+<input type="hidden" name="format" value="table">
+<input type="hidden" name="action" value="plot">
 <hr>
 
 [% PROCESS "search/boolean-charts.html.tmpl" %]
 [%############################################################################%]
 
 [% BLOCK select %]
-  [% fields = [
-    { name => "",                 description => "---" },
-    { name => "product",          description => "Product" },
-    { name => "component",        description => "Component" },
-    { name => "version",          description => "Version" },
-    { name => "rep_platform",     description => "Platform" },
-    { name => "op_sys",           description => "OS" },
-    { name => "bug_status",       description => "Status" },
-    { name => "resolution",       description => "Resolution" },
-    { name => "bug_severity",     description => "Severity" },
-    { name => "priority",         description => "Priority" },
-    { name => "target_milestone", description => "Target Milestone" },
-    { name => "keywords",         description => "Keywords" },
-    { name => "assigned_to",      description => "Assignee" },
-    { name => "reporter",         description => "Reporter" },
-    { name => "qa_contact",       description => "QA Contact" },
-    { name => "votes",            description => "Votes" } ] %]
+  [% fields = ["product", "component", "version", "rep_platform",  
+               "op_sys", "bug_status", "resolution", "bug_severity", 
+               "priority", "target_milestone", "keywords", "assigned_to",
+               "reporter", "qa_contact", "votes" ] %]
 
   <select name="[% sel.name %]">
+    [% IF sel.noop %]
+      <option value="">&lt;none&gt;</option>
+    [% END %]
+    
     [% FOREACH field = fields %]
-      [% NEXT IF field.name == "" AND !sel.noop %]
-      [% NEXT IF field.name == "target_milestone" AND
-                               !Param('usetargetmilestone') %]
-      [% NEXT IF field.name == "qa_contact" AND !Param('useqacontact') %]
-      [% NEXT IF field.name == "votes" AND !Param('usevotes') %]
+      [% NEXT IF field == "target_milestone" AND !Param('usetargetmilestone') %]
+      [% NEXT IF field == "qa_contact" AND !Param('useqacontact') %]
+      [% NEXT IF field == "votes" AND !Param('usevotes') %]
       
-      <option value="[% field.name FILTER html %]" 
-        [% " selected" IF default.${sel.name}.0 == field.name %]>
-        [% field.description FILTER html %]</option>
+      <option value="[% field FILTER html %]" 
+        [% " selected" IF default.${sel.name}.0 == field %]>
+        [% field_descs.$field || field FILTER html %]</option>
     [% END %]
   </select>
 [% END %]