aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md2
-rw-r--r--perllib/FixMyStreet/App/Controller/Dashboard.pm122
-rw-r--r--perllib/FixMyStreet/App/Controller/Reports.pm4
-rw-r--r--perllib/FixMyStreet/Cobrand/BathNES.pm36
-rw-r--r--perllib/FixMyStreet/Cobrand/Zurich.pm2
-rw-r--r--perllib/FixMyStreet/DB/Result/Comment.pm49
-rw-r--r--t/app/controller/dashboard.t36
-rw-r--r--t/cobrand/bathnes.t81
-rw-r--r--templates/web/base/dashboard/index.html6
-rw-r--r--web/cobrands/sass/_dashboard.scss17
10 files changed, 258 insertions, 97 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6f7fbacfc..a0a3d2d5d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,8 @@
## Releases
* Unreleased
+ - New features:
+ - Dashboard now has update CSV export. #2249
- Front end improvements:
- Clearer relocation options while you’re reporting a problem #2238
- Bugfixes:
diff --git a/perllib/FixMyStreet/App/Controller/Dashboard.pm b/perllib/FixMyStreet/App/Controller/Dashboard.pm
index aadd913ca..14042732e 100644
--- a/perllib/FixMyStreet/App/Controller/Dashboard.pm
+++ b/perllib/FixMyStreet/App/Controller/Dashboard.pm
@@ -112,10 +112,14 @@ sub index : Path : Args(0) {
$c->stash->{end_date} = $c->get_param('end_date');
$c->stash->{q_state} = $c->get_param('state') || '';
- $c->forward('construct_rs_filter');
+ $c->forward('construct_rs_filter', [ $c->get_param('updates') ]);
if ( $c->get_param('export') ) {
- $c->forward('export_as_csv');
+ if ($c->get_param('updates')) {
+ $c->forward('export_as_csv_updates');
+ } else {
+ $c->forward('export_as_csv');
+ }
} else {
$c->forward('generate_grouped_data');
$self->generate_summary_figures($c);
@@ -123,7 +127,7 @@ sub index : Path : Args(0) {
}
sub construct_rs_filter : Private {
- my ($self, $c) = @_;
+ my ($self, $c, $updates) = @_;
my %where;
$where{areas} = { 'like', '%,' . $c->stash->{ward} . ',%' }
@@ -131,28 +135,31 @@ sub construct_rs_filter : Private {
$where{category} = $c->stash->{category}
if $c->stash->{category};
+ my $table_name = $updates ? 'problem' : 'me';
+
my $state = $c->stash->{q_state};
if ( FixMyStreet::DB::Result::Problem->fixed_states->{$state} ) { # Probably fixed - council
- $where{'me.state'} = [ FixMyStreet::DB::Result::Problem->fixed_states() ];
+ $where{"$table_name.state"} = [ FixMyStreet::DB::Result::Problem->fixed_states() ];
} elsif ( $state ) {
- $where{'me.state'} = $state;
+ $where{"$table_name.state"} = $state;
} else {
- $where{'me.state'} = [ FixMyStreet::DB::Result::Problem->visible_states() ];
+ $where{"$table_name.state"} = [ FixMyStreet::DB::Result::Problem->visible_states() ];
}
my $dtf = $c->model('DB')->storage->datetime_parser;
my $start_date = $dtf->parse_datetime($c->stash->{start_date});
- $where{'me.confirmed'} = { '>=', $dtf->format_datetime($start_date) };
+ $where{"$table_name.confirmed"} = { '>=', $dtf->format_datetime($start_date) };
if (my $end_date = $c->stash->{end_date}) {
my $one_day = DateTime::Duration->new( days => 1 );
$end_date = $dtf->parse_datetime($end_date) + $one_day;
- $where{'me.confirmed'} = [ -and => $where{'me.confirmed'}, { '<', $dtf->format_datetime($end_date) } ];
+ $where{"$table_name.confirmed"} = [ -and => $where{"$table_name.confirmed"}, { '<', $dtf->format_datetime($end_date) } ];
}
$c->stash->{params} = \%where;
- $c->stash->{problems_rs} = $c->cobrand->problems->to_body($c->stash->{body})->search( \%where );
+ my $rs = $updates ? $c->cobrand->updates : $c->cobrand->problems;
+ $c->stash->{objects_rs} = $rs->to_body($c->stash->{body})->search( \%where );
}
sub generate_grouped_data : Private {
@@ -184,7 +191,7 @@ sub generate_grouped_data : Private {
@groups = qw/category state/;
%grouped = map { $_->category => {} } @{$c->stash->{contacts}};
}
- my $problems = $c->stash->{problems_rs}->search(undef, {
+ my $problems = $c->stash->{objects_rs}->search(undef, {
group_by => [ map { ref $_ ? $_->{-as} : $_ } @groups ],
select => [ @groups, { count => 'me.id' } ],
as => [ @groups == 2 ? qw/key1 key2 count/ : qw/key1 count/ ],
@@ -240,7 +247,7 @@ sub generate_summary_figures {
# problems this month by state
$c->stash->{"summary_$_"} = 0 for values %$state_map;
- $c->stash->{summary_open} = $c->stash->{problems_rs}->count;
+ $c->stash->{summary_open} = $c->stash->{objects_rs}->count;
my $params = $c->stash->{params};
$params = { map { my $n = $_; s/me\./problem\./ unless /me\.confirmed/; $_ => $params->{$n} } keys %$params };
@@ -274,11 +281,49 @@ sub generate_body_response_time : Private {
$c->stash->{body_average} = $avg ? int($avg / 60 / 60 / 24 + 0.5) : 0;
}
+sub csv_filename {
+ my ($self, $c, $updates) = @_;
+ my %where = (
+ category => $c->stash->{category},
+ state => $c->stash->{q_state},
+ ward => $c->stash->{ward},
+ );
+ $where{body} = $c->stash->{body}->id if $c->stash->{body};
+ join '-',
+ $c->req->uri->host,
+ $updates ? ('updates') : (),
+ map {
+ my $value = $where{$_};
+ (defined $value and length $value) ? ($_, $value) : ()
+ } sort keys %where
+};
+
+sub export_as_csv_updates : Private {
+ my ($self, $c) = @_;
+
+ my $csv = $c->stash->{csv} = {
+ objects => $c->stash->{objects_rs}->search_rs({}, {
+ order_by => ['me.confirmed', 'me.id'],
+ }),
+ headers => [
+ 'Report ID', 'Update ID', 'Date', 'Status', 'Problem state',
+ 'Text', 'User Name', 'Reported As',
+ ],
+ columns => [
+ 'problem_id', 'id', 'confirmed', 'state', 'problem_state',
+ 'text', 'user_name_display', 'reported_as',
+ ],
+ filename => $self->csv_filename($c, 1),
+ };
+ $c->cobrand->call_hook("dashboard_export_updates_add_columns");
+ $c->forward('generate_csv');
+}
+
sub export_as_csv : Private {
my ($self, $c) = @_;
my $csv = $c->stash->{csv} = {
- problems => $c->stash->{problems_rs}->search_rs({}, {
+ objects => $c->stash->{objects_rs}->search_rs({}, {
prefetch => 'comments',
order_by => ['me.confirmed', 'me.id'],
}),
@@ -300,6 +345,8 @@ sub export_as_csv : Private {
'Easting',
'Northing',
'Report URL',
+ 'Site Used',
+ 'Reported As',
],
columns => [
'id',
@@ -319,23 +366,12 @@ sub export_as_csv : Private {
'local_coords_x',
'local_coords_y',
'url',
+ 'site_used',
+ 'reported_as',
],
- filename => do {
- my %where = (
- category => $c->stash->{category},
- state => $c->stash->{q_state},
- ward => $c->stash->{ward},
- );
- $where{body} = $c->stash->{body}->id if $c->stash->{body};
- join '-',
- $c->req->uri->host,
- map {
- my $value = $where{$_};
- (defined $value and length $value) ? ($_, $value) : ()
- } sort keys %where
- },
+ filename => $self->csv_filename($c, 0),
};
- $c->cobrand->call_hook("dashboard_export_add_columns");
+ $c->cobrand->call_hook("dashboard_export_problems_add_columns");
$c->forward('generate_csv');
}
@@ -356,6 +392,9 @@ hashref of extra data to include that can be used by 'columns'.
sub generate_csv : Private {
my ($self, $c) = @_;
+ # Old parameter renaming
+ $c->stash->{csv}->{objects} //= $c->stash->{csv}->{problems};
+
my $csv = Text::CSV->new({ binary => 1, eol => "\n" });
$csv->combine(@{$c->stash->{csv}->{headers}});
my @body = ($csv->string);
@@ -365,15 +404,15 @@ sub generate_csv : Private {
my %asked_for = map { $_ => 1 } @{$c->stash->{csv}->{columns}};
- my $problems = $c->stash->{csv}->{problems};
- while ( my $report = $problems->next ) {
- my $hashref = $report->as_hashref($c, \%asked_for);
+ my $objects = $c->stash->{csv}->{objects};
+ while ( my $obj = $objects->next ) {
+ my $hashref = $obj->as_hashref($c, \%asked_for);
- $hashref->{user_name_display} = $report->anonymous
- ? '(anonymous)' : $report->name;
+ $hashref->{user_name_display} = $obj->anonymous
+ ? '(anonymous)' : $obj->name;
if ($asked_for{acknowledged}) {
- for my $comment ($report->comments) {
+ for my $comment ($obj->comments) {
my $problem_state = $comment->problem_state or next;
next unless $comment->state eq 'confirmed';
next if $problem_state eq 'confirmed';
@@ -394,12 +433,21 @@ sub generate_csv : Private {
split ',', $hashref->{areas};
}
- ($hashref->{local_coords_x}, $hashref->{local_coords_y}) =
- $report->local_coords;
- $hashref->{url} = join '', $c->cobrand->base_url_for_report($report), $report->url;
+ if ($obj->can('local_coords')) {
+ ($hashref->{local_coords_x}, $hashref->{local_coords_y}) =
+ $obj->local_coords;
+ }
+ if ($obj->can('url')) {
+ my $base = $c->cobrand->base_url_for_report($obj->can('problem') ? $obj->problem : $obj);
+ $hashref->{url} = join '', $base, $obj->url;
+ }
+
+ $hashref->{site_used} = $obj->can('service') ? ($obj->service || $obj->cobrand) : $obj->cobrand;
+
+ $hashref->{reported_as} = $obj->get_extra_metadata('contributed_as') || '';
if (my $fn = $c->stash->{csv}->{extra_data}) {
- my $extra = $fn->($report);
+ my $extra = $fn->($obj);
$hashref = { %$hashref, %$extra };
}
diff --git a/perllib/FixMyStreet/App/Controller/Reports.pm b/perllib/FixMyStreet/App/Controller/Reports.pm
index 356578bb0..1ca4cbb09 100644
--- a/perllib/FixMyStreet/App/Controller/Reports.pm
+++ b/perllib/FixMyStreet/App/Controller/Reports.pm
@@ -461,7 +461,7 @@ sub summary : Private {
$c->forward('/admin/fetch_contacts');
$c->stash->{contacts} = [ $c->stash->{contacts}->all ];
- $c->forward('/dashboard/construct_rs_filter');
+ $c->forward('/dashboard/construct_rs_filter', []);
if ( $c->get_param('csv') ) {
$c->detach('export_summary_csv');
@@ -477,7 +477,7 @@ sub export_summary_csv : Private {
my ( $self, $c ) = @_;
$c->stash->{csv} = {
- problems => $c->stash->{problems_rs}->search_rs({}, {
+ objects => $c->stash->{objects_rs}->search_rs({}, {
rows => 100,
order_by => { '-desc' => 'me.confirmed' },
}),
diff --git a/perllib/FixMyStreet/Cobrand/BathNES.pm b/perllib/FixMyStreet/Cobrand/BathNES.pm
index c02c9328c..b341f7c5b 100644
--- a/perllib/FixMyStreet/Cobrand/BathNES.pm
+++ b/perllib/FixMyStreet/Cobrand/BathNES.pm
@@ -206,7 +206,33 @@ sub categories_restriction {
] } );
}
-sub dashboard_export_add_columns {
+sub dashboard_export_updates_add_columns {
+ my $self = shift;
+ my $c = $self->{c};
+
+ return unless $c->user->has_body_permission_to('export_extra_columns');
+
+ push @{$c->stash->{csv}->{headers}}, "Staff User";
+ push @{$c->stash->{csv}->{headers}}, "User Email";
+ push @{$c->stash->{csv}->{columns}}, "staff_user";
+ push @{$c->stash->{csv}->{columns}}, "user_email";
+
+ $c->stash->{csv}->{extra_data} = sub {
+ my $report = shift;
+
+ my $staff_user = '';
+ if ( my $contributed_by = $report->get_extra_metadata('contributed_by') ) {
+ $staff_user = $c->model('DB::User')->find({ id => $contributed_by })->email;
+ }
+
+ return {
+ user_email => $report->user->email || '',
+ staff_user => $staff_user,
+ };
+ };
+}
+
+sub dashboard_export_problems_add_columns {
my $self = shift;
my $c = $self->{c};
@@ -216,39 +242,31 @@ sub dashboard_export_add_columns {
@{ $c->stash->{csv}->{headers} },
"User Email",
"User Phone",
- "Reported As",
"Staff User",
"Attribute Data",
- "Site Used",
];
$c->stash->{csv}->{columns} = [
@{ $c->stash->{csv}->{columns} },
"user_email",
"user_phone",
- "reported_as",
"staff_user",
"attribute_data",
- "site_used",
];
$c->stash->{csv}->{extra_data} = sub {
my $report = shift;
- my $reported_as = $report->get_extra_metadata('contributed_as') || '';
my $staff_user = '';
if ( my $contributed_by = $report->get_extra_metadata('contributed_by') ) {
$staff_user = $c->model('DB::User')->find({ id => $contributed_by })->email;
}
- my $site_used = $report->service || $report->cobrand || '';
my $attribute_data = join "; ", map { $_->{name} . " = " . $_->{value} } @{ $report->get_extra_fields };
return {
user_email => $report->user->email || '',
user_phone => $report->user->phone || '',
- reported_as => $reported_as,
staff_user => $staff_user,
attribute_data => $attribute_data,
- site_used => $site_used,
};
};
}
diff --git a/perllib/FixMyStreet/Cobrand/Zurich.pm b/perllib/FixMyStreet/Cobrand/Zurich.pm
index 7a54fe0d5..7740474ab 100644
--- a/perllib/FixMyStreet/Cobrand/Zurich.pm
+++ b/perllib/FixMyStreet/Cobrand/Zurich.pm
@@ -1205,7 +1205,7 @@ sub export_as_csv {
try {
$c->model('DB')->schema->storage->sql_maker->quote_char('"');
my $csv = $c->stash->{csv} = {
- problems => $c->model('DB::Problem')->search_rs(
+ objects => $c->model('DB::Problem')->search_rs(
$params,
{
join => ['admin_log_entries', 'user'],
diff --git a/perllib/FixMyStreet/DB/Result/Comment.pm b/perllib/FixMyStreet/DB/Result/Comment.pm
index 8a4dbe475..b4e42b456 100644
--- a/perllib/FixMyStreet/DB/Result/Comment.pm
+++ b/perllib/FixMyStreet/DB/Result/Comment.pm
@@ -253,24 +253,22 @@ sub meta_line {
return $meta;
};
+sub problem_state_processed {
+ my $self = shift;
+ return 'fixed - user' if $self->mark_fixed;
+ return 'confirmed' if $self->mark_open;
+ return $self->problem_state;
+}
+
sub problem_state_display {
my ( $self, $c ) = @_;
- my $update_state = '';
- my $cobrand = $c->cobrand->moniker;
-
- if ($self->mark_fixed) {
- return FixMyStreet::DB->resultset("State")->display('fixed', 1);
- } elsif ($self->mark_open) {
- return FixMyStreet::DB->resultset("State")->display('confirmed', 1);
- } elsif ($self->problem_state) {
- my $state = $self->problem_state;
- my $cobrand_name = $cobrand;
- $cobrand_name = 'bromley' if $self->problem->to_body_named('Bromley');
- $update_state = FixMyStreet::DB->resultset("State")->display($state, 1, $cobrand_name);
- }
+ my $state = $self->problem_state_processed;
+ return '' unless $state;
- return $update_state;
+ my $cobrand_name = $c->cobrand->moniker;
+ $cobrand_name = 'bromley' if $self->problem->to_body_named('Bromley');
+ return FixMyStreet::DB->resultset("State")->display($state, 1, $cobrand_name);
}
sub is_latest {
@@ -298,4 +296,27 @@ sub hide {
return $ret;
}
+sub as_hashref {
+ my ($self, $c, $cols) = @_;
+
+ my $out = {
+ id => $self->id,
+ problem_id => $self->problem_id,
+ text => $self->text,
+ state => $self->state,
+ created => $self->created,
+ };
+
+ $out->{problem_state} = $self->problem_state_processed;
+
+ $out->{photos} = [ map { $_->{url} } @{$self->photos} ] if !$cols || $cols->{photos};
+
+ if ($self->confirmed) {
+ $out->{confirmed} = $self->confirmed if !$cols || $cols->{confirmed};
+ $out->{confirmed_pp} = $c->cobrand->prettify_dt( $self->confirmed ) if !$cols || $cols->{confirmed_pp};
+ }
+
+ return $out;
+}
+
1;
diff --git a/t/app/controller/dashboard.t b/t/app/controller/dashboard.t
index b53056968..3a031bec3 100644
--- a/t/app/controller/dashboard.t
+++ b/t/app/controller/dashboard.t
@@ -43,9 +43,13 @@ foreach my $problem (@fixed_problems) {
$mech->create_comment_for_problem($problem, $counciluser, 'Title', 'text', 0, 'confirmed', 'fixed');
}
+my $first_problem_id;
+my $first_update_id;
foreach my $problem (@closed_problems) {
$problem->update({ state => 'closed' });
- $mech->create_comment_for_problem($problem, $counciluser, 'Title', 'text', 0, 'confirmed', 'closed', { confirmed => \'current_timestamp' });
+ my ($update) = $mech->create_comment_for_problem($problem, $counciluser, 'Title', 'text', 0, 'confirmed', 'closed', { confirmed => \'current_timestamp' });
+ $first_problem_id = $problem->id unless $first_problem_id;
+ $first_update_id = $update->id unless $first_update_id;
}
my $categories = scraper {
@@ -154,7 +158,7 @@ FixMyStreet::override_config {
}
is scalar @rows, 19, '1 (header) + 18 (reports) = 19 lines';
- is scalar @{$rows[0]}, 18, '18 columns present';
+ is scalar @{$rows[0]}, 20, '20 columns present';
is_deeply $rows[0],
[
@@ -176,6 +180,8 @@ FixMyStreet::override_config {
'Easting',
'Northing',
'Report URL',
+ 'Site Used',
+ 'Reported As',
],
'Column headers look correct';
@@ -184,6 +190,32 @@ FixMyStreet::override_config {
is $rows[5]->[16], '179716', 'Correct Northing conversion';
};
+ subtest 'export updates as csv' => sub {
+ $mech->get_ok('/dashboard?updates=1&export=1');
+ open my $data_handle, '<', \$mech->content;
+ my $csv = Text::CSV->new( { binary => 1 } );
+ my @rows;
+ while ( my $row = $csv->getline( $data_handle ) ) {
+ push @rows, $row;
+ }
+ is scalar @rows, 15, '1 (header) + 14 (updates) = 15 lines';
+ is scalar @{$rows[0]}, 8, '8 columns present';
+
+ is_deeply $rows[0],
+ [
+ 'Report ID', 'Update ID', 'Date', 'Status', 'Problem state',
+ 'Text', 'User Name', 'Reported As',
+ ],
+ 'Column headers look correct';
+
+ is $rows[1]->[0], $first_problem_id, 'Correct report ID';
+ is $rows[1]->[1], $first_update_id, 'Correct update ID';
+ is $rows[1]->[3], 'confirmed', 'Correct state';
+ is $rows[1]->[4], 'closed', 'Correct problem state';
+ is $rows[1]->[5], 'text', 'Correct text';
+ is $rows[1]->[6], 'Title', 'Correct name';
+ };
+
subtest 'export as csv using token' => sub {
$mech->log_out_ok;
diff --git a/t/cobrand/bathnes.t b/t/cobrand/bathnes.t
index e0ad07c16..59e0d5246 100644
--- a/t/cobrand/bathnes.t
+++ b/t/cobrand/bathnes.t
@@ -72,7 +72,7 @@ subtest 'extra CSV columns are absent if permission not granted' => sub {
}
is scalar @rows, 5, '1 (header) + 4 (reports) = 5 lines';
- is scalar @{$rows[0]}, 18, '18 columns present';
+ is scalar @{$rows[0]}, 20, '20 columns present';
is_deeply $rows[0],
[
@@ -94,6 +94,8 @@ subtest 'extra CSV columns are absent if permission not granted' => sub {
'Easting',
'Northing',
'Report URL',
+ 'Site Used',
+ 'Reported As',
],
'Column headers look correct';
};
@@ -153,42 +155,61 @@ subtest 'extra CSV columns are present if permission granted' => sub {
'Easting',
'Northing',
'Report URL',
+ 'Site Used',
+ 'Reported As',
'User Email',
'User Phone',
- 'Reported As',
'Staff User',
'Attribute Data',
- 'Site Used',
],
'Column headers look correct';
- is $rows[1]->[18], 'normaluser@example.com', 'User email is correct';
- is $rows[1]->[19], '+447123456789', 'User phone number is correct';
- is $rows[1]->[20], '', 'Reported As is empty if not made on behalf of another user/body';
- is $rows[1]->[21], '', 'Staff User is empty if not made on behalf of another user';
- is $rows[1]->[22], 'width = 10cm; depth = 25cm', 'Attribute Data is correct';
- is $rows[1]->[23], 'iOS', 'Site Used shows whether report made via app';
-
- is $rows[2]->[18], 'counciluser@example.com', 'User email is correct';
- is $rows[2]->[19], '', 'User phone number is correct';
- is $rows[2]->[20], 'body', 'Reported As is correct if made on behalf of body';
- is $rows[2]->[21], '', 'Staff User is empty if not made on behalf of another user';
- is $rows[2]->[22], '', 'Attribute Data is correct';
- is $rows[2]->[23], 'bathnes', 'Site Used shows correct cobrand';
-
- is $rows[3]->[18], 'normaluser@example.com', 'User email is correct';
- is $rows[3]->[19], '+447123456789', 'User phone number is correct';
- is $rows[3]->[20], 'another_user', 'Reported As is set if reported on behalf of another user';
- is $rows[3]->[21], 'counciluser@example.com', 'Staff User is correct if made on behalf of another user';
- is $rows[3]->[22], '', 'Attribute Data is correct';
- is $rows[3]->[23], 'bathnes', 'Site Used shows correct cobrand';
-
- is $rows[4]->[18], 'counciluser@example.com', 'User email is correct';
- is $rows[4]->[19], '', 'User phone number is correct';
- is $rows[4]->[20], 'anonymous_user', 'Reported As is set if reported on behalf of another user';
- is $rows[4]->[21], '', 'Staff User is empty if not made on behalf of another user';
- is $rows[4]->[22], '', 'Attribute Data is correct';
- is $rows[4]->[23], 'bathnes', 'Site Used shows correct cobrand';
+ is $rows[1]->[18], 'iOS', 'Site Used shows whether report made via app';
+ is $rows[1]->[19], '', 'Reported As is empty if not made on behalf of another user/body';
+ is $rows[1]->[20], 'normaluser@example.com', 'User email is correct';
+ is $rows[1]->[21], '+447123456789', 'User phone number is correct';
+ is $rows[1]->[22], '', 'Staff User is empty if not made on behalf of another user';
+ is $rows[1]->[23], 'width = 10cm; depth = 25cm', 'Attribute Data is correct';
+
+ is $rows[2]->[18], 'bathnes', 'Site Used shows correct cobrand';
+ is $rows[2]->[19], 'body', 'Reported As is correct if made on behalf of body';
+ is $rows[2]->[20], 'counciluser@example.com', 'User email is correct';
+ is $rows[2]->[21], '', 'User phone number is correct';
+ is $rows[2]->[22], '', 'Staff User is empty if not made on behalf of another user';
+ is $rows[2]->[23], '', 'Attribute Data is correct';
+
+ is $rows[3]->[18], 'bathnes', 'Site Used shows correct cobrand';
+ is $rows[3]->[19], 'another_user', 'Reported As is set if reported on behalf of another user';
+ is $rows[3]->[20], 'normaluser@example.com', 'User email is correct';
+ is $rows[3]->[21], '+447123456789', 'User phone number is correct';
+ is $rows[3]->[22], 'counciluser@example.com', 'Staff User is correct if made on behalf of another user';
+ is $rows[3]->[23], '', 'Attribute Data is correct';
+
+ is $rows[4]->[18], 'bathnes', 'Site Used shows correct cobrand';
+ is $rows[4]->[19], 'anonymous_user', 'Reported As is set if reported on behalf of another user';
+ is $rows[4]->[20], 'counciluser@example.com', 'User email is correct';
+ is $rows[4]->[21], '', 'User phone number is correct';
+ is $rows[4]->[22], '', 'Staff User is empty if not made on behalf of another user';
+ is $rows[4]->[23], '', 'Attribute Data is correct';
+
+ $mech->get_ok('/dashboard?export=1&updates=1');
+
+ open $data_handle, '<', \$mech->content;
+ $csv = Text::CSV->new( { binary => 1 } );
+ @rows = ();
+ while ( my $row = $csv->getline( $data_handle ) ) {
+ push @rows, $row;
+ }
+
+ is scalar @rows, 1, '1 (header) + 0 (updates)';
+ is scalar @{$rows[0]}, 10, '10 columns present';
+ is_deeply $rows[0],
+ [
+ 'Report ID', 'Update ID', 'Date', 'Status', 'Problem state',
+ 'Text', 'User Name', 'Reported As', 'Staff User',
+ 'User Email',
+ ],
+ 'Column headers look correct';
};
diff --git a/templates/web/base/dashboard/index.html b/templates/web/base/dashboard/index.html
index 5377fa938..7c3966b04 100644
--- a/templates/web/base/dashboard/index.html
+++ b/templates/web/base/dashboard/index.html
@@ -102,7 +102,11 @@
<li>[% INCLUDE gb new_gb='month' text=loc('Month') %]</li>
<li>[% INCLUDE gb new_gb='category+state' text=loc('Category and State') %]</li>
<li>[% INCLUDE gb new_gb='device+site' text=loc('Device and Site') %]</li>
- <li class="pull-right"><a href="[% c.uri_with({ export => 1 }) %]">[% loc('Export as CSV') %]</a></li>
+ <li class="pull-right">
+ <span>[% loc('Export as CSV') %]:</span>
+ <a href="[% c.uri_with({ export => 1 }) %]">[% loc('Reports') %]</a>
+ <a href="[% c.uri_with({ export => 1, updates => 1 }) %]">[% loc('Updates') %]</a>
+ </li>
</ul>
<table width="100%" id="overview">
diff --git a/web/cobrands/sass/_dashboard.scss b/web/cobrands/sass/_dashboard.scss
index 6827a8225..28e587c75 100644
--- a/web/cobrands/sass/_dashboard.scss
+++ b/web/cobrands/sass/_dashboard.scss
@@ -297,6 +297,19 @@
li {
float: $left;
+ margin: 0 0.4em;
+
+ &:first-child {
+ margin-left: 0;
+ }
+
+ &:last-child {
+ margin-right: 0;
+ }
+
+ & > * + * {
+ margin-left: 0.4em;
+ }
}
.pull-right {
@@ -305,7 +318,7 @@
a, span, strong {
display: inline-block;
- padding: 0.4em 0.8em;
+ padding: 0.4em 0;
}
strong {
@@ -314,6 +327,8 @@
border-bottom-color: #fff;
border-radius: 0.3em 0.3em 0 0;
margin-bottom: -1px;
+ padding-left: 0.8em;
+ padding-right: 0.8em;
}
}