aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--perllib/FixMyStreet/App/Controller/Admin.pm10
-rw-r--r--perllib/FixMyStreet/App/Controller/Dashboard.pm126
-rw-r--r--perllib/FixMyStreet/App/Controller/Report.pm30
-rw-r--r--perllib/FixMyStreet/Cobrand/Bromley.pm33
-rw-r--r--perllib/FixMyStreet/DB/Result/User.pm2
-rw-r--r--t/app/controller/report_new.t2
-rwxr-xr-xtemplates/web/bromley/around/display_location.html2
-rw-r--r--templates/web/bromley/index.html2
-rw-r--r--templates/web/bromley/report/display.html8
-rw-r--r--templates/web/default/dashboard/index.html131
-rw-r--r--web/cobrands/fixmystreet/_base.scss6
-rw-r--r--web/cobrands/fixmystreet/_layout.scss2
-rw-r--r--web/cobrands/fixmystreet/fixmystreet.js2
13 files changed, 341 insertions, 15 deletions
diff --git a/perllib/FixMyStreet/App/Controller/Admin.pm b/perllib/FixMyStreet/App/Controller/Admin.pm
index 42e218f61..d11f1645e 100644
--- a/perllib/FixMyStreet/App/Controller/Admin.pm
+++ b/perllib/FixMyStreet/App/Controller/Admin.pm
@@ -547,8 +547,7 @@ sub report_edit : Path('report_edit') : Args(1) {
}
)->first;
- $c->detach( '/page_error_404_not_found',
- [ _('The requested URL was not found on this server.') ] )
+ $c->detach( '/page_error_404_not_found' )
unless $problem;
$c->stash->{problem} = $problem;
@@ -710,8 +709,7 @@ sub update_edit : Path('update_edit') : Args(1) {
}
)->first;
- $c->detach( '/page_error_404_not_found',
- [ _('The requested URL was not found on this server.') ] )
+ $c->detach( '/page_error_404_not_found' )
unless $update;
$c->forward('get_token');
@@ -1044,7 +1042,7 @@ sub check_token : Private {
my ( $self, $c ) = @_;
if ( !$c->req->param('token') || $c->req->param('token' ) ne $c->stash->{token} ) {
- $c->detach( '/page_error_404_not_found', [ _('The requested URL was not found on this server.') ] );
+ $c->detach( '/page_error_404_not_found' );
}
return 1;
@@ -1214,7 +1212,7 @@ sub check_page_allowed : Private {
$page ||= 'summary';
if ( !grep { $_ eq $page } keys %{ $c->stash->{allowed_pages} } ) {
- $c->detach( '/page_error_404_not_found', [ _('The requested URL was not found on this server.') ] );
+ $c->detach( '/page_error_404_not_found' );
}
return 1;
diff --git a/perllib/FixMyStreet/App/Controller/Dashboard.pm b/perllib/FixMyStreet/App/Controller/Dashboard.pm
new file mode 100644
index 000000000..6c327d479
--- /dev/null
+++ b/perllib/FixMyStreet/App/Controller/Dashboard.pm
@@ -0,0 +1,126 @@
+package FixMyStreet::App::Controller::Dashboard;
+use Moose;
+use namespace::autoclean;
+
+use DateTime;
+
+BEGIN { extends 'Catalyst::Controller'; }
+
+=head1 NAME
+
+FixMyStreet::App::Controller::Dashboard - Catalyst Controller
+
+=head1 DESCRIPTION
+
+Catalyst Controller.
+
+=head1 METHODS
+
+=cut
+
+=head2 check_page_allowed
+
+Checks if we can view this page, and if not redirect to 404.
+
+=cut
+
+sub check_page_allowed : Private {
+ my ( $self, $c ) = @_;
+
+ $c->detach( '/auth/redirect' ) unless $c->user_exists;
+
+ $c->detach( '/page_error_404_not_found' )
+ unless $c->user_exists && $c->user->from_council;
+
+ return $c->user->from_council;
+}
+
+=head2 index
+
+Show the dashboard table.
+
+=cut
+
+sub index : Path : Args(0) {
+ my ( $self, $c ) = @_;
+
+ my $council = $c->forward('check_page_allowed');
+
+ my $children = mySociety::MaPit::call('area/children', $council,
+ type => $mySociety::VotingArea::council_child_types,
+ );
+ $c->stash->{children} = $children;
+
+ my %counts;
+ my $t = DateTime->today;
+
+ $counts{wtd} = $c->forward( 'updates_search', [ {
+ council => $council,
+ 'me.confirmed' => { '>=', $t->subtract( days => $t->dow - 1 )
+ } } ] );
+
+ $counts{week} = $c->forward( 'updates_search', [ {
+ council => $council,
+ 'me.confirmed' => { '>=', DateTime->now->subtract( weeks => 1 )
+ } } ] );
+
+ $counts{weeks} = $c->forward( 'updates_search', [ {
+ council => $council,
+ 'me.confirmed' => { '>=', DateTime->now->subtract( weeks => 4 )
+ } } ] );
+
+ $counts{ytd} = $c->forward( 'updates_search', [ {
+ council => $council,
+ 'me.confirmed' => { '>=', DateTime->today->set( day => 1, month => 1 )
+ } } ] );
+
+ $c->stash->{problems} = \%counts;
+}
+
+sub updates_search : Private {
+ my ( $self, $c, $params ) = @_;
+
+ my $comments = $c->model('DB::Comment')->search(
+ $params,
+ {
+ group_by => [ 'problem_state' ],
+ select => [ 'problem_state', { count => 'me.id' } ],
+ as => [ qw/state state_count/ ],
+ join => 'problem'
+ }
+ );
+
+ my %counts =
+ map { ($_->state||'-') => $_->get_column('state_count') } $comments->all;
+ %counts =
+ map { $_ => $counts{$_} || 0 }
+ ('confirmed', 'investigating', 'in progress', 'closed', 'fixed - council',
+ 'fixed - user', 'fixed', 'unconfirmed', 'hidden',
+ 'partial', 'planned');
+
+ $counts{fixed_user} = $c->model('DB::Comment')->search(
+ { %$params, mark_fixed => 1 }, { join => 'problem' }
+ )->count;
+
+ $counts{total} = $c->cobrand->problems->search(
+ { %$params, state => [ FixMyStreet::DB::Result::Problem::visible_states() ] }
+ )->count;
+
+ return \%counts;
+}
+
+=head1 AUTHOR
+
+Matthew Somerville
+
+=head1 LICENSE
+
+Copyright (c) 2012 UK Citizens Online Democracy. All rights reserved.
+Licensed under the Affero GPL.
+
+=cut
+
+__PACKAGE__->meta->make_immutable;
+
+1;
+
diff --git a/perllib/FixMyStreet/App/Controller/Report.pm b/perllib/FixMyStreet/App/Controller/Report.pm
index afe180c29..cca625bd5 100644
--- a/perllib/FixMyStreet/App/Controller/Report.pm
+++ b/perllib/FixMyStreet/App/Controller/Report.pm
@@ -153,6 +153,36 @@ sub generate_map_tags : Private {
return 1;
}
+sub delete :Local :Args(1) {
+ my ( $self, $c, $id ) = @_;
+
+ $c->forward( 'load_problem_or_display_error', [ $id ] );
+ my $p = $c->stash->{problem};
+
+ my $uri = $c->uri_for( '/report', $id );
+
+ return $c->res->redirect($uri) unless $c->user_exists;
+
+ my $council = $c->user->obj->from_council;
+ return $c->res->redirect($uri) unless $council;
+
+ my %councils = map { $_ => 1 } @{$p->councils};
+ return $c->res->redirect($uri) unless $councils{$council};
+
+ $p->state('hidden');
+ $p->lastupdate( \'ms_current_timestamp()' );
+ $p->update;
+
+ $c->model('DB::AdminLog')->create( {
+ admin_user => $c->user->email,
+ object_type => 'problem',
+ action => 'state_change',
+ object_id => $id,
+ } );
+
+ return $c->res->redirect($uri);
+}
+
__PACKAGE__->meta->make_immutable;
1;
diff --git a/perllib/FixMyStreet/Cobrand/Bromley.pm b/perllib/FixMyStreet/Cobrand/Bromley.pm
index acdefb41e..5bc292306 100644
--- a/perllib/FixMyStreet/Cobrand/Bromley.pm
+++ b/perllib/FixMyStreet/Cobrand/Bromley.pm
@@ -36,6 +36,10 @@ sub example_places {
return ( 'BR1 3UH', 'Glebe Rd, Bromley' );
}
+sub on_map_default_max_pin_age {
+ return '1 month';
+}
+
sub recent_photos {
my ( $self, $area, $num, $lat, $lon, $dist ) = @_;
$num = 3 if $num > 3 && $area eq 'alert';
@@ -44,10 +48,37 @@ sub recent_photos {
sub pin_colour {
my ( $self, $p ) = @_;
- return 'green' if time() - $p->confirmed_local->epoch < 7 * 24 * 60 * 60;
+ #return 'green' if time() - $p->confirmed_local->epoch < 7 * 24 * 60 * 60;
return 'yellow';
}
+# Copy of function from FixMyStreet.pm cobrand as it's not inherited currently
+sub generate_problem_banner {
+ my ( $self, $problem ) = @_;
+
+ my $banner = {};
+ if ( $problem->is_open && time() - $problem->lastupdate_local->epoch > 8 * 7 * 24 * 60 * 60 )
+ {
+ $banner->{id} = 'unknown';
+ $banner->{text} = _('Unknown');
+ }
+ if ($problem->is_fixed) {
+ $banner->{id} = 'fixed';
+ $banner->{text} = _('Fixed');
+ }
+ if ($problem->is_closed) {
+ $banner->{id} = 'closed';
+ $banner->{text} = _('Closed');
+ }
+
+ if ( grep { $problem->state eq $_ } ( 'investigating', 'in progress', 'planned' ) ) {
+ $banner->{id} = 'progress';
+ $banner->{text} = _('In progress');
+ }
+
+ return $banner;
+}
+
sub process_extras {
my $self = shift;
my $ctx = shift;
diff --git a/perllib/FixMyStreet/DB/Result/User.pm b/perllib/FixMyStreet/DB/Result/User.pm
index 6788447d7..7f43d1a52 100644
--- a/perllib/FixMyStreet/DB/Result/User.pm
+++ b/perllib/FixMyStreet/DB/Result/User.pm
@@ -195,7 +195,7 @@ sub split_name {
my ($first, $last) = $self->name =~ /^(\S*)(?: (.*))?$/;
- return { first => $first, last => $last };
+ return { first => $first || '', last => $last || '' };
}
1;
diff --git a/t/app/controller/report_new.t b/t/app/controller/report_new.t
index 4a8cbbbfe..5fc6e6a5d 100644
--- a/t/app/controller/report_new.t
+++ b/t/app/controller/report_new.t
@@ -731,7 +731,7 @@ subtest "check that a lat/lon off coast leads to /around" => sub {
is $mech->uri->path, '/around', "redirected to '/around'";
is_deeply #
- $mech->page_errors,
+ $mech->form_errors,
[ 'That spot does not appear to be covered by a council. If you have'
. ' tried to report an issue past the shoreline, for example, please'
. ' specify the closest point on land.' ], #
diff --git a/templates/web/bromley/around/display_location.html b/templates/web/bromley/around/display_location.html
index d2726e035..b961ef4c6 100755
--- a/templates/web/bromley/around/display_location.html
+++ b/templates/web/bromley/around/display_location.html
@@ -70,7 +70,7 @@
<div id="side">
<h1 class="big-green-banner">[% loc( 'Click map to report a problem' ) %]
- <span>Pins show existing reports</span></h1>
+ <span>Yellow pins show existing reports</span></h1>
<p id="skip-this-step">
[%
diff --git a/templates/web/bromley/index.html b/templates/web/bromley/index.html
index 4b95230df..aeb4cc01c 100644
--- a/templates/web/bromley/index.html
+++ b/templates/web/bromley/index.html
@@ -21,7 +21,7 @@ Modernizr.load({
<h1 class="main mob-only">Reporting a problem in Bromley&rsquo;s streets or parks</h1>
[% IF error %]
- <p class="error">[% error %]</p>
+ <p class="form-error">[% error %]</p>
[% END %]
<div id="front-main">
diff --git a/templates/web/bromley/report/display.html b/templates/web/bromley/report/display.html
index fd74ac8db..c1a938b71 100644
--- a/templates/web/bromley/report/display.html
+++ b/templates/web/bromley/report/display.html
@@ -24,7 +24,13 @@
<div class="shadow-wrap">
<ul id="key-tools">
- <li><a rel="nofollow" id="key-tool-report-abuse" class="abuse" href="[% c.uri_for( '/contact', { id => problem.id } ) %]">[% loc('Report abuse' ) %]</a></li>
+ [% IF c.user_exists AND c.user.council == 'Bromley Council' %]
+ <li><form method="post" action="/report/delete/[% problem.id %]">
+ <input type="submit" class="abuse" value="Remove from site">
+ </form></li>
+ [% ELSE %]
+ <li><a rel="nofollow" id="key-tool-report-abuse" class="abuse" href="[% c.uri_for( '/contact', { id => problem.id } ) %]">[% loc('Report abuse') %]</a></li>
+ [% END %]
<li><a rel="nofollow" id="key-tool-report-updates" class="feed" href="[% c.uri_for( '/alert/subscribe', { id => problem.id } ) %]">[% loc('Get updates' ) %]</a></li>
<li><a class="chevron" id="key-tool-problems-nearby" href="[% c.uri_for( '/around', { lat => short_latitude, lon => short_longitude } ) %]">[% loc( 'Problems nearby' ) %]</a></li>
</ul>
diff --git a/templates/web/default/dashboard/index.html b/templates/web/default/dashboard/index.html
new file mode 100644
index 000000000..c54635b2a
--- /dev/null
+++ b/templates/web/default/dashboard/index.html
@@ -0,0 +1,131 @@
+[%
+ INCLUDE 'header.html'
+ title = loc('Dashboard')
+ robots = 'noindex, nofollow'
+ bodyclass = 'fullwidthpage'
+%]
+
+<style>
+ th[scope=row] { text-align: left; }
+ tr.subtotal { background-color: #eee; }
+ #overview tr:nth-child(2) { background-color: #fee; }
+</style>
+
+<p>Ward: <select name="ward"><option>All</option>
+ [% FOR ward IN children.values.sort('name') %]
+ <option value="[% ward.id %]">[% ward.name %]</option>
+ [% END %]
+</select>
+
+<h2>Performance Overview</h2>
+
+<p>Report category: <select name="category"><option>All</option>
+ [% FOR category IN categories %]
+ <option></option>
+ [% END %]
+</select>
+
+<table width="100%" id="overview">
+ <tr>
+ <td>&nbsp;</td>
+ <th scope="col">WTD</th>
+ <th scope="col">Last 7 days</th>
+ <th scope="col">Last 4 weeks</th>
+ <th scope="col">YTD</th>
+ </tr>
+
+ [%
+ rows = {
+ '0' => [ "total", "Total reports received" ]
+ '1' => [ "fixed - council", "Council has marked as fixed" ]
+ '2' => [ "fixed_user", "User has marked as fixed" ]
+ };
+ FOR row IN rows %]
+ <tr>
+ <th scope="row">[% row.value.1 %]</th>
+ <td>[% problems.wtd.${row.value.0} %]</td>
+ <td>[% problems.week.${row.value.0} %]</td>
+ <td>[% problems.weeks.${row.value.0} %]</td>
+ <td>[% problems.ytd.${row.value.0} %]</td>
+ </tr>
+ [% END %]
+
+ <tr class='subtotal'>
+ <th scope="row">Total marked as fixed</th>
+ <td>[% problems.wtd.${"fixed - council"} + problems.wtd.fixed_user %]</td>
+ <td>[% problems.week.${"fixed - council"} + problems.week.fixed_user %]</td>
+ <td>[% problems.weeks.${"fixed - council"} + problems.weeks.fixed_user %]</td>
+ <td>[% problems.ytd.${"fixed - council"} + problems.ytd.fixed_user %]</td>
+ </tr>
+
+ [%
+ rows = {
+ '0' => [ "in progress", "Council has marked as in progress" ]
+ '1' => [ "planned", "Council has marked as planned" ]
+ '2' => [ "investigating", "Council has marked as investigating" ]
+ };
+ wtd = 0, week = 0, weeks = 0, ytd = 0;
+ FOR row IN rows %]
+ <tr>
+ <th scope="row">[% row.value.1 %]</th>
+ <td>[% problems.wtd.${row.value.0} %]</td>
+ <td>[% problems.week.${row.value.0} %]</td>
+ <td>[% problems.weeks.${row.value.0} %]</td>
+ <td>[% problems.ytd.${row.value.0} %]</td>
+ </tr>
+ [% END %]
+
+ <tr class='subtotal'>
+ <th scope="row">Total marked</th>
+ <td>[% problems.wtd.${"in progress"} + problems.wtd.planned + problems.wtd.investigating %]</td>
+ <td>[% problems.week.${"in progress"} + problems.week.planned + problems.week.investigating %]</td>
+ <td>[% problems.weeks.${"in progress"} + problems.weeks.planned + problems.weeks.investigating %]</td>
+ <td>[% problems.ytd.${"in progress"} + problems.ytd.planned + problems.ytd.investigating %]</td>
+ </tr>
+
+ <tr>
+ <th scope="row">Average time to fix</th>
+ <td>-</td>
+ <td>-</td>
+ <td>-</td>
+ <td>-</td>
+ </tr>
+
+ <tr>
+ <th scope="row">Average time to mark</th>
+ <td>-</td>
+ <td>-</td>
+ <td>-</td>
+ <td>-</td>
+ </tr>
+
+ <tr class='subtotal'>
+ <th scope="row">Total not marked</th>
+ <td>-</td>
+ <td>-</td>
+ <td>-</td>
+ <td>-</td>
+ </tr>
+
+</table>
+
+<h2>Reports</h2>
+
+<p>Report state: <select name="state"><option>All</option></select>
+
+<table width="100%">
+ <tr>
+ <th scope="col">Less than 7 days old</th>
+ <th scope="col">7-14 days old</th>
+ <th scope="col">14-30 days old</th>
+ <th scope="col">30+ days old</th>
+ </tr>
+ <tr>
+ <td><ul><li></li></ul></td>
+ <td><ul><li></li></ul></td>
+ <td><ul><li></li></ul></td>
+ <td><ul><li></li></ul></td>
+ </tr>
+</table>
+
+[% INCLUDE 'footer.html' %]
diff --git a/web/cobrands/fixmystreet/_base.scss b/web/cobrands/fixmystreet/_base.scss
index ef60a8bef..bc8616954 100644
--- a/web/cobrands/fixmystreet/_base.scss
+++ b/web/cobrands/fixmystreet/_base.scss
@@ -529,7 +529,11 @@ p.label-valid {
&:last-child {
border-right:none;
}
- a {
+ input[type=submit] {
+ width: 100%;
+ border: none;
+ }
+ a, input[type=submit] {
display: block;
background-color: #f5f5f5;
background-repeat: no-repeat;
diff --git a/web/cobrands/fixmystreet/_layout.scss b/web/cobrands/fixmystreet/_layout.scss
index 5756d4df3..207c6a4c4 100644
--- a/web/cobrands/fixmystreet/_layout.scss
+++ b/web/cobrands/fixmystreet/_layout.scss
@@ -592,7 +592,7 @@ body.twothirdswidthpage {
@include box-shadow(-0em 0px 1em 1em #fff);
li {
border:none;
- a {
+ a, input[type=submit] {
font-size: 0.75em;
color:#666;
padding: 0.5em 1.5em 0.5em 0;
diff --git a/web/cobrands/fixmystreet/fixmystreet.js b/web/cobrands/fixmystreet/fixmystreet.js
index f65d8083a..b674020b1 100644
--- a/web/cobrands/fixmystreet/fixmystreet.js
+++ b/web/cobrands/fixmystreet/fixmystreet.js
@@ -143,7 +143,7 @@ $(function(){
// Remove full-screen-ness
var banner_text;
if (cobrand == 'bromley') {
- banner_text = 'Click map to report a problem<span>Pins show existing reports</span>';
+ banner_text = 'Click map to report a problem<span>Yellow pins show existing reports</span>';
} else {
$('#site-header').show();
banner_text = 'Click map to report a problem';