]> git.ipfire.org Git - thirdparty/bugzilla.git/commitdiff
Bug 863745: Enable multi-select fields in reports
authorPami Ketolainen <pami.ketolainen@jollamobile.com>
Tue, 29 Oct 2013 11:58:45 +0000 (12:58 +0100)
committerFrédéric Buclin <LpSolit@gmail.com>
Tue, 29 Oct 2013 11:58:45 +0000 (12:58 +0100)
r=LpSolit a=glob

Bugzilla/Search.pm
report.cgi
skins/standard/reports.css
template/en/default/filterexceptions.pl
template/en/default/reports/report-table.html.tmpl

index 7bd4381ed11822e98a6f4a1a4e9183457922a73d..e89a9b361f9188a3be02c12af767b32c6ed154ff 100644 (file)
@@ -656,12 +656,7 @@ sub REPORT_COLUMNS {
     # or simply don't work with the current reporting system.
     my @no_report_columns = 
         qw(bug_id alias short_short_desc opendate changeddate
-           flagtypes.name keywords relevance);
-
-    # Multi-select fields are not currently supported.
-    my @multi_selects = @{Bugzilla->fields(
-        { obsolete => 0, type => FIELD_TYPE_MULTI_SELECT })};
-    push(@no_report_columns, map { $_->name } @multi_selects);
+           flagtypes.name relevance);
 
     # If you're not a time-tracker, you can't use time-tracking
     # columns.
@@ -2863,9 +2858,10 @@ sub _multiselect_table {
 sub _multiselect_term {
     my ($self, $args, $not) = @_;
     my ($operator) = $args->{operator};
+    my $value = $args->{value} || '';
     # 'empty' operators require special handling
     return $self->_multiselect_isempty($args, $not)
-        if $operator =~ /^is(not)?empty$/;
+        if ($operator =~ /^is(not)?empty$/ || $value eq '---');
     my $table = $self->_multiselect_table($args);
     $self->_do_operator_function($args);
     my $term = $args->{term};
index 3a1130f2df59f366d8236b98210f9f4e7be460bc..cefe96d5a9c4240df49ed1946b482ffc9cfa653b 100755 (executable)
@@ -185,20 +185,64 @@ my $col_isnumeric = 1;
 my $row_isnumeric = 1;
 my $tbl_isnumeric = 1;
 
+# define which fields are multiselect
+my @multi_selects = map { $_->name } @{Bugzilla->fields(
+    {
+        obsolete => 0,
+        type => [FIELD_TYPE_MULTI_SELECT, FIELD_TYPE_KEYWORDS]
+    }
+)};
+my $col_ismultiselect = scalar grep {$col_field eq $_} @multi_selects;
+my $row_ismultiselect = scalar grep {$row_field eq $_} @multi_selects;
+my $tbl_ismultiselect = scalar grep {$tbl_field eq $_} @multi_selects;
+
+
 foreach my $result (@$results) {
     # handle empty dimension member names
-    my $row = check_value($row_field, $result);
-    my $col = check_value($col_field, $result);
-    my $tbl = check_value($tbl_field, $result);
-
-    $data{$tbl}{$col}{$row}++;
-    $names{"col"}{$col}++;
-    $names{"row"}{$row}++;
-    $names{"tbl"}{$tbl}++;
     
-    $col_isnumeric &&= ($col =~ /^-?\d+(\.\d+)?$/o);
-    $row_isnumeric &&= ($row =~ /^-?\d+(\.\d+)?$/o);
-    $tbl_isnumeric &&= ($tbl =~ /^-?\d+(\.\d+)?$/o);
+    my @rows = check_value($row_field, $result, $row_ismultiselect);
+    my @cols = check_value($col_field, $result, $col_ismultiselect);
+    my @tbls = check_value($tbl_field, $result, $tbl_ismultiselect);
+
+    my %in_total_row;
+    my %in_total_col;
+    for my $tbl (@tbls) {
+        my %in_row_total;
+        for my $col (@cols) {
+            for my $row (@rows) {
+                $data{$tbl}{$col}{$row}++;
+                $names{"row"}{$row}++;
+                $row_isnumeric &&= ($row =~ /^-?\d+(\.\d+)?$/o);
+                if ($formatparam eq "table") {
+                    if (!$in_row_total{$row}) {
+                        $data{$tbl}{'-total-'}{$row}++;
+                        $in_row_total{$row} = 1;
+                    }
+                    if (!$in_total_row{$row}) {
+                        $data{'-total-'}{'-total-'}{$row}++;
+                        $in_total_row{$row} = 1;
+                    }
+                }
+            }
+            if ($formatparam eq "table") {
+                $data{$tbl}{$col}{'-total-'}++;
+                if (!$in_total_col{$col}) {
+                    $data{'-total-'}{$col}{'-total-'}++;
+                    $in_total_col{$col} = 1;
+                }
+            }
+            $names{"col"}{$col}++;
+            $col_isnumeric &&= ($col =~ /^-?\d+(\.\d+)?$/o);
+        }
+        $names{"tbl"}{$tbl}++;
+        $tbl_isnumeric &&= ($tbl =~ /^-?\d+(\.\d+)?$/o);
+        if ($formatparam eq "table") {
+            $data{$tbl}{'-total-'}{'-total-'}++;
+        }
+    }
+    if ($formatparam eq "table") {
+        $data{'-total-'}{'-total-'}{'-total-'}++;
+    }
 }
 
 my @col_names = get_names($names{"col"}, $col_isnumeric, $col_field);
@@ -242,6 +286,7 @@ $vars->{'time'} = localtime(time());
 $vars->{'col_names'} = \@col_names;
 $vars->{'row_names'} = \@row_names;
 $vars->{'tbl_names'} = \@tbl_names;
+$vars->{'note_multi_select'} = $row_ismultiselect || $col_ismultiselect;
 
 # Below a certain width, we don't see any bars, so there needs to be a minimum.
 if ($formatparam eq "bar") {
@@ -352,7 +397,8 @@ sub get_names {
         foreach my $value (@{$field->legal_values}) {
             push(@sorted, $value->name) if $names->{$value->name};
         }
-        unshift(@sorted, '---') if $field_name eq 'resolution';
+        unshift(@sorted, '---') if ($field_name eq 'resolution'
+                                    || $field->type == FIELD_TYPE_MULTI_SELECT);
         @sorted = uniq @sorted;
     }  
     elsif ($isnumeric) {
@@ -369,7 +415,7 @@ sub get_names {
 }
 
 sub check_value {
-    my ($field, $result) = @_;
+    my ($field, $result, $ismultiselect) = @_;
 
     my $value;
     if (!defined $field) {
@@ -381,9 +427,15 @@ sub check_value {
     else {
         $value = shift @$result;
         $value = ' ' if (!defined $value || $value eq '');
-        $value = '---' if ($field eq 'resolution' && $value eq ' ');
+        $value = '---' if (($field eq 'resolution' || $ismultiselect ) &&
+                           $value eq ' ');
+    }
+    if ($ismultiselect) {
+        # Some DB servers have a space after the comma, some others don't.
+        return split(/, ?/, $value);
+    } else {
+        return ($value);
     }
-    return $value;
 }
 
 sub get_field_restrictions {
index 97ef316ba0e21efdfca0b23b02188494feb4d7bd..8e0ddf1b0e06f03b2359134a93102cfc28d53940 100644 (file)
   max-width: 100%;
   height: auto;
 }
+
+.extra_info {
+  font-size: smaller;
+  font-style: italic;
+}
\ No newline at end of file
index 239b6828cdf8e1ce23bb48a85216a5b5e116ade2..2270f0919f8ff3615cf9e4696067e76c985a4fb9 100644 (file)
@@ -78,9 +78,6 @@
   'classes.$row_idx.$col_idx', 
   'urlbase', 
   'data.$tbl.$col.$row', 
-  'row_total',
-  'col_totals.$col',
-  'grand_total', 
 ],
 
 'reports/report.html.tmpl' => [
index 2747166beb0c1868ad42932ee293f0f3a5dfcf3e..927a389174ac7d4f4235f51d36de96d6c605a994 100644 (file)
@@ -156,7 +156,7 @@ YAHOO.util.Event.addListener(window, "load", function() {
 [% classes = [ [ "t1", "t2" ] , [ "t3", "t4" ] ] %]
 [% col_idx = 0 %]
 [% row_idx = 0 %]
-[% grand_total = 0 %]
+[% total_key = '-total-' %]
 <div id="tabular_report_container_[% tbl FILTER html %]">
 <table id="tabular_report" border="1">
   [% IF col_field %]
@@ -165,7 +165,6 @@ YAHOO.util.Event.addListener(window, "load", function() {
       <th class="[% classes.$row_idx.$col_idx %]">
       </th>
       [% FOREACH col = col_names %]
-        [% col_totals.$col = 0 %]
         [% NEXT IF col == "" %]
         
         [% col_idx = 1 - col_idx %]
@@ -181,17 +180,13 @@ YAHOO.util.Event.addListener(window, "load", function() {
   [% END %]
   <tbody>
   [% FOREACH row = row_names %]
-    [% row_total = 0 %]
-    
     [% row_idx = 1 - row_idx %]
     <tr>
       <td class="[% classes.$row_idx.$col_idx %]" align="right">
         [% PROCESS value_display value = row field = row_field %]
       </td>
       [% FOREACH col = col_names %]
-        [% row_total = row_total + data.$tbl.$col.$row %]
         [% NEXT IF col == "" %]
-        [% col_totals.$col = (col_totals.$col || 0) + data.$tbl.$col.$row %]
         
         [% col_idx = 1 - col_idx %]
         <td class="[% classes.$row_idx.$col_idx %]" align="center">
@@ -209,8 +204,7 @@ YAHOO.util.Event.addListener(window, "load", function() {
         <a href="[% urlbase %]&amp;
           [% row_field FILTER uri %]=[% row FILTER uri %]
           [% "&amp;$col_vals" IF col_vals %]">
-        [% row_total %]</a>
-        [% grand_total = grand_total + row_total %]
+        [% data.$tbl.$total_key.$row OR 0 FILTER html %]</a>
       </td>
     </tr>
   [% END %]
@@ -221,19 +215,19 @@ YAHOO.util.Event.addListener(window, "load", function() {
       </td>
       [% FOREACH col = col_names %]
         [% NEXT IF col == "" %]
-      
+
         <td class="ttotal" align="center">
           <a href="[% urlbase %]&amp;
             [% col_field FILTER uri %]=[% col FILTER uri %]
             [% "&amp;$row_vals" IF row_vals %]">
-          [% col_totals.$col %]</a>
+          [% data.$tbl.$col.$total_key OR 0 FILTER html %]</a>
         </td>
       [% END %]
       <td class="ttotal" align="right">
         <strong>
           <a href="[% urlbase %]
             [% "&amp;$row_vals" IF row_vals %]
-            [% "&amp;$col_vals" IF col_vals %]">[% grand_total %]</a>
+            [% "&amp;$col_vals" IF col_vals %]">[% data.$tbl.$total_key.$total_key OR 0 FILTER html %]</a>
         </strong>
       </td>
     </tr>
@@ -245,6 +239,13 @@ YAHOO.util.Event.addListener(window, "load", function() {
   </tr>
 </table>
 
+[% IF note_multi_select %]
+  <p class="extra_info">
+    NOTE: Axes contain multi-value fields, so the total numbers might not add up,
+    as a single [% terms.bug %] can match several rows or columns.
+  </p>
+[% END %]
+
 [% BLOCK value_display %]
   [% SET disp_value = display_value(field, value) %]
   [% IF field == 'assigned_to' OR field == 'reporter'