diff options
author | Matthew Somerville <matthew-github@dracos.co.uk> | 2018-10-05 12:04:11 +0100 |
---|---|---|
committer | Matthew Somerville <matthew-github@dracos.co.uk> | 2018-10-05 12:04:11 +0100 |
commit | 06d166694a9253b99a9c2720266b8b5cdc557d0f (patch) | |
tree | f8901aabcea9871cf96dc5a8c3d20a134af5f9cf | |
parent | c358aa2beeb4637d190a91def6c7a4b23d162b51 (diff) | |
parent | cdffddc061b58a61e78fe230bef2f0271baec006 (diff) |
Merge branch 'dashboard-update-csv-export'
-rw-r--r-- | CHANGELOG.md | 2 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Dashboard.pm | 122 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Reports.pm | 4 | ||||
-rw-r--r-- | perllib/FixMyStreet/Cobrand/BathNES.pm | 36 | ||||
-rw-r--r-- | perllib/FixMyStreet/Cobrand/Zurich.pm | 2 | ||||
-rw-r--r-- | perllib/FixMyStreet/DB/Result/Comment.pm | 49 | ||||
-rw-r--r-- | t/app/controller/dashboard.t | 36 | ||||
-rw-r--r-- | t/cobrand/bathnes.t | 81 | ||||
-rw-r--r-- | templates/web/base/dashboard/index.html | 6 | ||||
-rw-r--r-- | web/cobrands/sass/_dashboard.scss | 17 |
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; } } |