diff options
-rw-r--r-- | Bugzilla/Search.pm | 10 | ||||
-rwxr-xr-x | report.cgi | 82 | ||||
-rw-r--r-- | skins/standard/reports.css | 5 | ||||
-rw-r--r-- | template/en/default/filterexceptions.pl | 3 | ||||
-rw-r--r-- | template/en/default/reports/report-table.html.tmpl | 23 |
5 files changed, 87 insertions, 36 deletions
diff --git a/Bugzilla/Search.pm b/Bugzilla/Search.pm index 7bd4381ed..e89a9b361 100644 --- a/Bugzilla/Search.pm +++ b/Bugzilla/Search.pm @@ -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}; diff --git a/report.cgi b/report.cgi index 3a1130f2d..cefe96d5a 100755 --- a/report.cgi +++ b/report.cgi @@ -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 { diff --git a/skins/standard/reports.css b/skins/standard/reports.css index 97ef316ba..8e0ddf1b0 100644 --- a/skins/standard/reports.css +++ b/skins/standard/reports.css @@ -102,3 +102,8 @@ max-width: 100%; height: auto; } + +.extra_info { + font-size: smaller; + font-style: italic; +}
\ No newline at end of file diff --git a/template/en/default/filterexceptions.pl b/template/en/default/filterexceptions.pl index 239b6828c..2270f0919 100644 --- a/template/en/default/filterexceptions.pl +++ b/template/en/default/filterexceptions.pl @@ -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' => [ diff --git a/template/en/default/reports/report-table.html.tmpl b/template/en/default/reports/report-table.html.tmpl index 2747166be..927a38917 100644 --- a/template/en/default/reports/report-table.html.tmpl +++ b/template/en/default/reports/report-table.html.tmpl @@ -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 %]& [% row_field FILTER uri %]=[% row FILTER uri %] [% "&$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 %]& [% col_field FILTER uri %]=[% col FILTER uri %] [% "&$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 %] [% "&$row_vals" IF row_vals %] - [% "&$col_vals" IF col_vals %]">[% grand_total %]</a> + [% "&$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' |