Skip to content

Commit

Permalink
[FMS] Add grouping to dashboard output
Browse files Browse the repository at this point in the history
Dashboard should collect categories under groups if they are in a group.

Currently, as we aren't distinguishing between which group a category
is in, filters out categories in multiple groups into a multiple
category.
  • Loading branch information
MorayMySoc committed Mar 5, 2024
1 parent e64460c commit 1b77531
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 11 deletions.
22 changes: 22 additions & 0 deletions perllib/FixMyStreet/App/Controller/Dashboard.pm
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ use Path::Tiny;
use Time::Piece;
use FixMyStreet::DateRange;
use FixMyStreet::Reporting;
use List::Util qw(uniq);
use List::MoreUtils qw(part);

BEGIN { extends 'Catalyst::Controller'; }

Expand Down Expand Up @@ -292,6 +294,26 @@ sub generate_grouped_data : Private {
my $bm = $map{$b} // $map{$state_map->{$b}};
$am <=> $bm;
} @rows;
} elsif ($group_by eq 'category+state' || $group_by eq 'category') {
@rows = ();
my @sorting_categories;

Check warning on line 299 in perllib/FixMyStreet/App/Controller/Dashboard.pm

View check run for this annotation

Codecov / codecov/patch

perllib/FixMyStreet/App/Controller/Dashboard.pm#L298-L299

Added lines #L298 - L299 were not covered by tests
my %category_to_group;
for my $group (@{$c->stash->{category_groups}}) {
for my $category (@{$group->{categories}}) {
push @sorting_categories, $category->category;

Check warning on line 303 in perllib/FixMyStreet/App/Controller/Dashboard.pm

View check run for this annotation

Codecov / codecov/patch

perllib/FixMyStreet/App/Controller/Dashboard.pm#L301-L303

Added lines #L301 - L303 were not covered by tests
if (!$category_to_group{$category->category}) {
$category_to_group{$category->category} = $group->{name};

Check warning on line 305 in perllib/FixMyStreet/App/Controller/Dashboard.pm

View check run for this annotation

Codecov / codecov/patch

perllib/FixMyStreet/App/Controller/Dashboard.pm#L305

Added line #L305 was not covered by tests
} else {
$category_to_group{$category->category} = 'Multiple';

Check warning on line 307 in perllib/FixMyStreet/App/Controller/Dashboard.pm

View check run for this annotation

Codecov / codecov/patch

perllib/FixMyStreet/App/Controller/Dashboard.pm#L307

Added line #L307 was not covered by tests
}
}
};
my ($single_group, $multiple_groups) = part { $category_to_group{$_} eq 'Multiple'} @sorting_categories;
my @multiple = sort (uniq(@$multiple_groups));

Check warning on line 312 in perllib/FixMyStreet/App/Controller/Dashboard.pm

View check run for this annotation

Codecov / codecov/patch

perllib/FixMyStreet/App/Controller/Dashboard.pm#L311-L312

Added lines #L311 - L312 were not covered by tests

push @rows, @$single_group if $single_group;
push @rows, @multiple if scalar @multiple;
$c->stash->{category_to_group} = \%category_to_group;

Check warning on line 316 in perllib/FixMyStreet/App/Controller/Dashboard.pm

View check run for this annotation

Codecov / codecov/patch

perllib/FixMyStreet/App/Controller/Dashboard.pm#L316

Added line #L316 was not covered by tests
} else {
@rows = sort @rows;
}
Expand Down
34 changes: 23 additions & 11 deletions t/app/controller/dashboard.t
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ my $categories = scraper {
process "table[id=overview] > tr", 'rows[]' => scraper {
process 'td', 'cols[]' => 'TEXT'
},
process 'th[scope=colgroup]', 'top_level[]' => 'TEXT'
};

my $UPLOAD_DIR = tempdir( CLEANUP => 1 );
Expand Down Expand Up @@ -166,48 +167,57 @@ FixMyStreet::override_config {
$mech->content_contains('<option value="group-Road &amp; more"');
is_deeply( $res->{cats}, $expected_cats, 'correct list of categories' );
# Three missing as more than a month ago
test_table($mech->content, 1, 0, 0, 1, 0, 0, 0, 0, 2, 0, 4, 6, 7, 3, 0, 10, 1, 0, 0, 1, 11, 3, 4, 18);
test_table($mech->content, 1, 0, 0, 1, 0, 0, 0, 0, 7, 3, 0, 10, 2, 0, 4, 6, 1, 0, 0, 1, 11, 3, 4, 18);
};

subtest 'test filters' => sub {
$mech->get_ok("/dashboard");
$mech->submit_form_ok({ with_fields => { category => 'Litter' } });
test_table($mech->content, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1);
$mech->submit_form_ok({ with_fields => { category => '', state => 'fixed - council' } });
test_table($mech->content, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4);
test_table($mech->content, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 0, 0, 0, 0, 4, 4);
$mech->submit_form_ok({ with_fields => { state => 'action scheduled' } });
test_table($mech->content, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, 0, 0, 0, 0, 7, 0, 0, 7);
test_table($mech->content, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7);
my $start = DateTime->now->subtract(months => 3)->strftime('%Y-%m-%d');
my $end = DateTime->now->subtract(months => 1)->strftime('%Y-%m-%d');
$mech->submit_form_ok({ with_fields => { state => '', start_date => $start, end_date => $end } });
test_table($mech->content, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 3, 0, 0, 0, 0, 3, 0, 0, 3);
test_table($mech->content, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 3);
$mech->get_ok("/dashboard?category=Litter&category=Potholes");
test_table($mech->content, 1, 0, 0, 1, 0, 0, 0, 0, 2, 0, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 4, 7);
test_table($mech->content, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 6, 0, 0, 0, 0, 3, 0, 4, 7);
$mech->get_ok("/dashboard?category=Traffic+lights+%26+bells");
$mech->content_contains("<option value='Traffic lights &amp; bells' selected>");
test_table($mech->content, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 0, 10, 0, 0, 0, 0, 7, 3, 0, 10);
test_table($mech->content, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 0, 10);
$mech->get_ok("/dashboard?category=group-Road+%26+more");
$mech->content_contains('<option value="group-Road &amp; more" selected>');
test_table($mech->content, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 6, 0, 0, 0, 0, 1, 0, 0, 1, 3, 0, 4, 7);
test_table($mech->content, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 6, 1, 0, 0, 1, 3, 0, 4, 7);
$mech->get_ok("/dashboard?category=group-Road+%26+more&category=Potholes");
test_table($mech->content, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 6, 0, 0, 0, 0, 1, 0, 0, 1, 3, 0, 4, 7);
test_table($mech->content, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 6, 1, 0, 0, 1, 3, 0, 4, 7);
$mech->get_ok("/dashboard?category=group-Road+%26+more&category=Litter");
test_table($mech->content, 1, 0, 0, 1, 0, 0, 0, 0, 2, 0, 4, 6, 0, 0, 0, 0, 1, 0, 0, 1, 4, 0, 4, 8);
test_table($mech->content, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 6, 1, 0, 0, 1, 4, 0, 4, 8);
};

subtest 'test grouping' => sub {
$mech->get_ok("/dashboard?group_by=category");
test_table($mech->content, 1, 0, 6, 10, 1, 18);
my $top_level = test_table($mech->content, 1, 0, 10, 6, 1, 18);
is_deeply $top_level, ['Road & more'], 'Road group created';
$mech->get_ok("/dashboard?group_by=state");
test_table($mech->content, 4, 7, 4, 3, 18);
$mech->get_ok("/dashboard?start_date=2000-01-01&group_by=month");
test_table($mech->content, 0, 18, 18, 3, 0, 3, 3, 18, 21);
my $pothole = FixMyStreet::DB->resultset('Contact')->find_or_create({ category => 'Potholes'});
$pothole->set_extra_metadata(group => ['Road & more', 'Pavement']);
$pothole->update;
$mech->get_ok("/dashboard?group_by=category");
$top_level = test_table($mech->content, 1, 0, 10, 1, 6, 18);
is_deeply $top_level, ['Road & more', 'Multiple'], 'Road and Multiple groups created';
$pothole->set_extra_metadata(group => ['Road & more']);
$pothole->update;
};

subtest 'test roles' => sub {
# All the fixed (Pothole) reports only
$mech->get_ok("/dashboard?group_by=category&role=" . $role->id);
test_table($mech->content, 0, 0, 4, 0, 0, 4);
test_table($mech->content, 0, 0, 0, 4, 0, 4);
$mech->get_ok("/dashboard?export=2&group_by=category&role=" . $role->id);
$mech->content_contains('role-' . $role->id, "File link created with role");
};
Expand Down Expand Up @@ -373,12 +383,14 @@ FixMyStreet::override_config {

sub test_table {
my ($content, @expected) = @_;

my $res = $categories->scrape( $mech->content );
my @actual;
foreach my $row ( @{ $res->{rows} }[1 .. 11] ) {
push @actual, @{$row->{cols}} if $row->{cols};
}
is_deeply \@actual, \@expected;
return $res->{top_level};
}

restore_time;
Expand Down
11 changes: 11 additions & 0 deletions templates/web/base/dashboard/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,18 @@ <h1>[% loc('Summary statistics') %]</h1>
<th scope="col">[% loc('Total') %]</th>
[% END %]
</tr>
[% SET current_category = '' %]
[% FOR k IN rows %][% k_safe = mark_safe(k) %]
[% IF category_to_group.$k_safe AND category_to_group.$k_safe != current_category %]
[% SET current_category = category_to_group.$k_safe %]
<tr>
[% IF group_by == 'category+state' %]
<th colspan="5" scope="colgroup">[% category_to_group.$k_safe %]</th>
[% ELSE %]
<th colspan="2" scope="colgroup">[% category_to_group.$k_safe %]</th>
[% END %]
</tr>
[% END %]
<tr>
[% IF group_by == 'state' %]
<th scope="row">[% prettify_state(k) %]</th>
Expand Down

0 comments on commit 1b77531

Please sign in to comment.