From: Pami Ketolainen Date: Tue, 29 Oct 2013 11:58:45 +0000 (+0100) Subject: Bug 863745: Enable multi-select fields in reports X-Git-Tag: bugzilla-4.5.2~107 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1622591fb61de5f8f2a2b482c9df5816d379892e;p=thirdparty%2Fbugzilla.git Bug 863745: Enable multi-select fields in reports r=LpSolit a=glob --- diff --git a/Bugzilla/Search.pm b/Bugzilla/Search.pm index 7bd4381ed1..e89a9b361f 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 3a1130f2df..cefe96d5a9 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 97ef316ba0..8e0ddf1b0e 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 239b6828cd..2270f0919f 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 2747166beb..927a389174 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-' %]
[% IF col_field %] @@ -165,7 +165,6 @@ YAHOO.util.Event.addListener(window, "load", function() { [% 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 %] [% FOREACH row = row_names %] - [% row_total = 0 %] - [% row_idx = 1 - row_idx %] [% 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 %] [% END %] @@ -221,19 +215,19 @@ YAHOO.util.Event.addListener(window, "load", function() { [% FOREACH col = col_names %] [% NEXT IF col == "" %] - + [% END %] @@ -245,6 +239,13 @@ YAHOO.util.Event.addListener(window, "load", function() {
[% PROCESS value_display value = row field = row_field %] @@ -209,8 +204,7 @@ YAHOO.util.Event.addListener(window, "load", function() { - [% row_total %] - [% grand_total = grand_total + row_total %] + [% data.$tbl.$total_key.$row OR 0 FILTER html %]
- [% col_totals.$col %] + [% data.$tbl.$col.$total_key OR 0 FILTER html %] [% grand_total %] + [% "&$col_vals" IF col_vals %]">[% data.$tbl.$total_key.$total_key OR 0 FILTER html %]
+[% IF note_multi_select %] +

+ 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. +

+[% END %] + [% BLOCK value_display %] [% SET disp_value = display_value(field, value) %] [% IF field == 'assigned_to' OR field == 'reporter'