Commit 1622591f authored by Pami Ketolainen's avatar Pami Ketolainen Committed by Frédéric Buclin

Bug 863745: Enable multi-select fields in reports

r=LpSolit a=glob
parent 4a1c14d4
......@@ -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};
......
......@@ -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 {
......
......@@ -102,3 +102,8 @@
max-width: 100%;
height: auto;
}
.extra_info {
font-size: smaller;
font-style: italic;
}
\ No newline at end of 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' => [
......
......@@ -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'
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment