Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
- Add created flag to inactive processing script. #5386
- Include report ID in main submit template. #5568
- Allow per-category timespan for closing inactive reports to updates. #5649
- Dashboard: toggle visibility of deleted categories and categories with no reports
- Development improvements
- More logging when `page_error` is called, to aid troubleshooting. #5279
- Docker changes needed for systemd to work. #5257
Expand Down
35 changes: 30 additions & 5 deletions perllib/FixMyStreet/App/Controller/Dashboard.pm
Original file line number Diff line number Diff line change
Expand Up @@ -143,14 +143,26 @@ sub index : Path : Args(0) {
$c->stash->{category} = [ $c->get_param_list('category') ];
my @remove_from_display;

# Determines which groups and categories are displayed in table
my %table_groups_and_categories;

foreach (@{$c->stash->{category}}) {
next unless /^group-(.*)/;
for my $contact (@{$group_names{$1}}) {
push @{ $c->stash->{category} }, $contact->category;
push @remove_from_display, $contact->category;
if ( /^group-(.*)/ ) {
$table_groups_and_categories{groups}{$1} = 1;

for my $contact (@{$group_names{$1}}) {
$table_groups_and_categories{$contact->category} = 1;
push @{ $c->stash->{category} }, $contact->category;
push @remove_from_display, $contact->category;
}
} else {
$table_groups_and_categories{$_} = 1;
}
}

$c->stash->{table_groups_and_categories}
= \%table_groups_and_categories;

my %display_categories = map { $_ => 1 } @{$c->stash->{category}};
delete $display_categories{$_} for (@remove_from_display);
$c->stash->{display_categories} = \%display_categories;
Expand Down Expand Up @@ -306,11 +318,25 @@ sub generate_grouped_data : Private {
push @sorting_categories, $category->category;
if (!$category_to_group{$category->category}) {
$category_to_group{$category->category} = $group->{name};

$c->stash->{group_to_category}{ $group->{name} }
{ $category->category }{state} = $category->state;

} else {
$category_to_group{$category->category} = 'Multiple';

$c->stash->{group_to_category}{'Multiple'}
{ $category->category }{state} = $category->state;

# Make sure 'Multiple' heading is displayed in table
$c->stash->{table_groups_and_categories}{groups}
{'Multiple'} = 1
if $c->stash->{table_groups_and_categories}
{ $category->category };
}
}
};

my ($single_group, $multiple_groups) = part { $category_to_group{$_} eq 'Multiple'} @sorting_categories;
my @multiple = sort (uniq(@$multiple_groups));

Expand Down Expand Up @@ -531,4 +557,3 @@ Licensed under the Affero GPL.
__PACKAGE__->meta->make_immutable;

1;

6 changes: 3 additions & 3 deletions t/cobrand/cyclinguk.t
Original file line number Diff line number Diff line change
Expand Up @@ -109,15 +109,15 @@ $mech->log_in_ok($super->email);
subtest 'cyclinguk dashboard shows correct report data' => sub {
$problem->update({ cobrand => 'fixmystreet'});
$mech->get_ok("/dashboard");
$mech->content_like(qr{th scope="row">Total</th>\s*<td>0</td>}, ".com reports not shown in dashboard");
$mech->content_like(qr{th scope="row">Total.*</th>\s*<td>0</td>}, ".com reports not shown in dashboard");

$problem->update({ cobrand => 'bathnes'});
$mech->get_ok("/dashboard");
$mech->content_like(qr{th scope="row">Total</th>\s*<td>0</td>}, "council cobrand reports not shown in dashboard");
$mech->content_like(qr{th scope="row">Total.*</th>\s*<td>0</td>}, "council cobrand reports not shown in dashboard");

$problem->update({ cobrand => 'cyclinguk'});
$mech->get_ok("/dashboard");
$mech->content_like(qr{th scope="row">Total</th>\s*<td>1</td>}, "cyclinguk cobrand reports are shown in dashboard");
$mech->content_like(qr{th scope="row">Total.*</th>\s*<td>1</td>}, "cyclinguk cobrand reports are shown in dashboard");
};

subtest 'cyclinguk dashboard shows correct bodies' => sub {
Expand Down
2 changes: 1 addition & 1 deletion t/cobrand/shropshire.t
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ FixMyStreet::override_config {
$mech->content_contains('Abdon and Heath');
$mech->submit_form_ok({ with_fields => { ward => 144013 } });
$mech->content_contains('<option value="144013" selected>Oswestry</option>');
$mech->content_like(qr{<th scope="row">Total</th>\s*<td>1</td>});
$mech->content_like(qr{<th scope="row">Total.*</th>\s*<td>1</td>});

$mech->get_ok('/dashboard/heatmap');
$mech->content_contains('Town/parish council');
Expand Down
76 changes: 59 additions & 17 deletions templates/web/base/dashboard/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
<link rel="stylesheet" href="[% version('/cobrands/fixmystreet/dashboard.css') %]">
[% END %]

[% extra_js = [
version('/cobrands/fixmystreet/dashboard.js')
] %]

[%
INCLUDE 'header.html'
title = loc('Dashboard')
Expand Down Expand Up @@ -63,7 +67,7 @@ <h1>[% loc('Summary statistics') %]</h1>
<select class="form-control js-multiple" multiple name="category" id="category">
[% BLOCK category_option %]
[% SET category_safe = mark_safe(cat.category) %]
<option value='[% cat.category | html %]'[% ' selected' IF display_categories.$category_safe %]>[% cat.category_display | html %]</option>
<option value='[% cat.category | html %]'[% ' selected' IF display_categories.$category_safe %]>[% cat.category_display | html %][% ' [deleted]' IF cat.state == 'deleted' %]</option>
[% END %]
[%~ INCLUDE 'report/new/_category_select.html' include_group_option=1 ~%]
</select>
Expand Down Expand Up @@ -166,36 +170,74 @@ <h1>[% loc('Summary statistics') %]</h1>
[% 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>
[% # 'current_category' denotes current group %]
[% SET current_category = category_to_group.$k_safe %]
<tr class="group-heading[% IF category.size && !(table_groups_and_categories.groups.$current_category) %] is-unselected-category[% END %]">
[% 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 %]
[% IF group_by == 'state' %]
<tr>
[% IF group_by == 'state' %]
<th scope="row">[% prettify_state(k) %]</th>
<th scope="row">[% prettify_state(k) %]</th>
[% ELSIF group_by == 'category+state' || group_by == 'category' %]
[% IF category.size %]
[%
# We do not want to mark/hide deleted/zero categories if searching for specific one(s).
# Instead, hide any unselected categories.
%]
[%
SET class_to_hide =
table_groups_and_categories.$k ?
'' :
'is-unselected-category';
%]
[% ELSE %]
<th scope="row">[% k %]</th>
[% # Mark/hide deleted/zero categories %]
[%
SET is_zero =
(
group_by == 'category+state'
&& !grouped.$k_safe.open
&& !grouped.$k_safe.closed
&& !grouped.$k_safe.fixed
) || (
group_by == 'category'
&& !grouped.$k_safe.total
);

SET class_to_hide =
group_to_category.$current_category.$k_safe.state == 'deleted' ?
'is-deleted' :
is_zero ?
'is-zero' :
'';
%]
[% END %]
[% IF group_by == 'category+state' %]
<td>[% grouped.$k_safe.open OR 0 %]</td>
<td>[% grouped.$k_safe.closed OR 0 %]</td>
<td>[% grouped.$k_safe.fixed OR 0 %]</td>
<td>[% grouped.$k_safe.total OR 0 %]</td>
[% ELSE %]
[% FOR k2 IN columns.sort %]
<td>[% grouped.$k_safe.$k2 OR 0 %]</td>
[% END %]
<td>[% grouped.$k_safe.total OR 0 %]</td>
<tr [% IF class_to_hide %]class="[% class_to_hide %]"[% END %]>
<th class="contact-category" scope="row">[% k %]</th>
[% ELSE %]
<tr>
<th scope="row">[% k %]</th>
[% END %]
[% IF group_by == 'category+state' %]
<td>[% grouped.$k_safe.open OR 0 %]</td>
<td>[% grouped.$k_safe.closed OR 0 %]</td>
<td>[% grouped.$k_safe.fixed OR 0 %]</td>
<td>[% grouped.$k_safe.total OR 0 %]</td>
[% ELSE %]
[% FOR k2 IN columns.sort %]
<td>[% grouped.$k_safe.$k2 OR 0 %]</td>
[% END %]
<td>[% grouped.$k_safe.total OR 0 %]</td>
[% END %]
</tr>
[% END %]
<tr class="subtotal">
<th scope="row">[% loc('Total') %]</th>
<th scope="row">[% loc('Total (including deleted categories)') %]</th>
[% IF group_by == 'category+state' %]
<td>[% totals.open OR 0 %]</td>
<td>[% totals.closed OR 0 %]</td>
Expand Down
81 changes: 81 additions & 0 deletions web/cobrands/fixmystreet/dashboard.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
$(function(){
var $table_with_zero_reports = $('table tr.is-zero').closest('table');
var $toggle_zeroes_btn = $("<input type='submit' class='btn' value='Show categories with zero reports' id='toggle-zeroes-btn' style='margin:1em 0;'/>");

// hide/show categories with zero reports
if ($table_with_zero_reports.length == 1) {
$table_with_zero_reports.before($toggle_zeroes_btn);
$toggle_zeroes_btn.on('click', function(e){
e.preventDefault();
var $cols = $table_with_zero_reports.find('tr.is-zero');
if ($cols.first().is(':visible')) {
$cols.hide();
$(this).prop("value", 'Show categories with zero reports');
} else {
$cols.show();
$(this).prop("value", 'Hide categories with zero reports');
}

toggleGroupHeadings();
});

var $table_with_deleted_contacts = $('table tr.is-deleted').closest('table');
var $toggle_deleted_btn = $("<input type='submit' class='btn' value='Show deleted categories' id='toggle-deleted-contacts-btn' style='margin:1em 0;'/>");

// hide/show deleted contact categories
if ($table_with_deleted_contacts.length == 1)
$table_with_deleted_contacts.before($toggle_deleted_btn);
$toggle_deleted_btn.on('click', function(e){
e.preventDefault();
var $cols = $table_with_deleted_contacts.find('tr.is-deleted');
if ($cols.first().is(':visible')) {
$cols.hide();
$(this).prop("value", 'Show deleted categories');
} else {
$cols.show();
$(this).prop("value", 'Hide deleted categories');
}

toggleGroupHeadings();
});
}

function toggleGroupHeadings() {
var $rows = $('table#overview tr');
var $current_group_heading;
var $visible_count = 0;

$rows.each( function( idx, elem ) {
if ( $(this).hasClass('group-heading') ) {
// Hide previous group heading if no visible categories
if ($current_group_heading) {
if ( $visible_count == 0 ) {
$current_group_heading.hide();
} else {
$current_group_heading.show();
}
}

// Then set next group heading
$current_group_heading = $(this);
$visible_count = 0;

} else if ( !$(this).hasClass('subtotal') ) {
if ( $(this).is(':visible') ) {
$visible_count++;
}
}
});

// Toggle final group heading
if ($current_group_heading) {
if ( $visible_count == 0 ) {
$current_group_heading.hide();
} else {
$current_group_heading.show();
}
}
}

toggleGroupHeadings();
});
17 changes: 17 additions & 0 deletions web/cobrands/fixmystreet/dashboard.scss
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,15 @@
padding-#{$left}: 10px;
}

tr.is-deleted {
background-color: #ffdddd;
th.contact-category {
text-decoration: line-through;
}
}
tr.is-zero {
background-color: #ddddff;
}
tr.subtotal {
background-color:#eee;
border-bottom:20px solid white;
Expand All @@ -48,6 +57,14 @@
}
}

tr.is-unselected-category {
display: none;
}

.js tr.is-deleted, .js tr.is-zero {
display: none;
}


#reports{
th {
Expand Down