aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Somerville <matthew@mysociety.org>2011-06-30 10:45:49 +0100
committerMatthew Somerville <matthew@mysociety.org>2011-06-30 10:45:49 +0100
commitfb78afe61194ea9b6fbec9596d69627e315ab97f (patch)
treee7c15dab1f918edfe6b57c33de02e95dea885fce
parent6db910f24b1c25bb32369fafde79cf0da83abed0 (diff)
Paginate Reports pages, and add a map.
-rw-r--r--conf/httpd.conf-example3
-rw-r--r--perllib/FixMyStreet/App/Controller/Reports.pm69
-rw-r--r--templates/web/default/maps/openlayers.html1
-rwxr-xr-xtemplates/web/default/reports/council.html71
-rw-r--r--web/js/map-OpenLayers.js18
5 files changed, 123 insertions, 39 deletions
diff --git a/conf/httpd.conf-example b/conf/httpd.conf-example
index 54c4b90ac..8abb13831 100644
--- a/conf/httpd.conf-example
+++ b/conf/httpd.conf-example
@@ -56,6 +56,9 @@ RewriteRule ^/alerts/?$ /alert [R=permanent,L]
RewriteRule /tilma/(.*) http://tilma.mysociety.org/$1 [P,L]
ProxyPassReverse /tilma/ http://tilma.mysociety.org/
+RewriteRule /mapit/(.*) http://mapit.mysociety.org/$1 [P,L]
+ProxyPassReverse /mapit/ http://mapit.mysociety.org/
+
# serve static files directly
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f
RewriteRule /(.+) /$1 [L]
diff --git a/perllib/FixMyStreet/App/Controller/Reports.pm b/perllib/FixMyStreet/App/Controller/Reports.pm
index a3aeb8505..e533ea347 100644
--- a/perllib/FixMyStreet/App/Controller/Reports.pm
+++ b/perllib/FixMyStreet/App/Controller/Reports.pm
@@ -93,10 +93,36 @@ sub ward : Path : Args(2) {
$c->forward( 'load_and_group_problems' );
$c->forward( 'sort_problems' );
- $c->stash->{rss_url} = '/rss/reports/'
- . $c->cobrand->short_name( $c->stash->{council}, $c->stash->{areas_info} );
+ my $council_short = $c->cobrand->short_name( $c->stash->{council}, $c->stash->{areas_info} );
+ $c->stash->{rss_url} = '/rss/reports/' . $council_short;
$c->stash->{rss_url} .= '/' . $c->cobrand->short_name( $c->stash->{ward} )
if $c->stash->{ward};
+
+ $c->stash->{council_url} = '/reports/' . $council_short;
+
+ my $pins = $c->stash->{pins};
+
+ # Even though front end doesn't yet have it, have it on this page, it's better!
+ FixMyStreet::Map::set_map_class( 'FMS' );
+ FixMyStreet::Map::display_map(
+ $c,
+ latitude => @$pins ? $pins->[0]{latitude} : 0,
+ longitude => @$pins ? $pins->[0]{longitude} : 0,
+ area => $c->stash->{ward} ? $c->stash->{ward}->{id} : $c->stash->{council}->{id},
+ pins => $pins,
+ any_zoom => 1,
+ );
+
+ # List of wards
+ unless ($c->stash->{ward}) {
+ my $children = mySociety::MaPit::call('area/children', $c->stash->{council}->{id} );
+ foreach (values %$children) {
+ $_->{url} = $c->uri_for( $c->stash->{council_url}
+ . '/' . $c->cobrand->short_name( $_ )
+ );
+ }
+ $c->stash->{children} = $children;
+ }
}
sub rss_council : Regex('^rss/(reports|area)$') : Args(1) {
@@ -258,41 +284,41 @@ sub load_parent : Private {
sub load_and_group_problems : Private {
my ( $self, $c ) = @_;
+ my $page = $c->req->params->{p} || 1;
+
my $where = {
state => [ 'confirmed', 'fixed' ]
};
- my @extra_cols = ();
if ($c->stash->{ward}) {
$where->{areas} = { 'like', '%' . $c->stash->{ward}->{id} . '%' }; # FIXME Check this is secure
- push @extra_cols, 'title', 'detail';
} elsif ($c->stash->{council}) {
$where->{areas} = { 'like', '%' . $c->stash->{council}->{id} . '%' };
- push @extra_cols, 'title', 'detail';
}
my $problems = $c->cobrand->problems->search(
$where,
{
columns => [
- 'id', 'council', 'state', 'areas',
+ 'id', 'council', 'state', 'areas', 'latitude', 'longitude', 'title',
{ duration => { extract => "epoch from current_timestamp-lastupdate" } },
{ age => { extract => "epoch from current_timestamp-confirmed" } },
- @extra_cols,
],
- order_by => { -desc => 'id' },
+ order_by => { -desc => 'lastupdate' },
+ rows => 100,
}
- );
+ )->page( $page );
+ $c->stash->{pager} = $problems->pager;
$problems = $problems->cursor; # Raw DB cursor for speed
- my ( %fixed, %open );
+ my ( %fixed, %open, @pins );
my $re_councils = join('|', keys %{$c->stash->{areas_info}});
- my @cols = ( 'id', 'council', 'state', 'areas', 'duration', 'age', 'title', 'detail' );
+ my @cols = ( 'id', 'council', 'state', 'areas', 'latitude', 'longitude', 'title', 'duration', 'age' );
while ( my @problem = $problems->next ) {
my %problem = zip @cols, @problem;
if ( !$problem{council} ) {
# Problem was not sent to any council, add to possible councils
$problem{councils} = 0;
while ($problem{areas} =~ /,($re_councils)(?=,)/g) {
- add_row( \%problem, $1, \%fixed, \%open );
+ add_row( \%problem, $1, \%fixed, \%open, \@pins );
}
} else {
# Add to councils it was sent to
@@ -301,13 +327,16 @@ sub load_and_group_problems : Private {
$problem{councils} = scalar @council;
foreach ( @council ) {
next if $c->stash->{council} && $_ != $c->stash->{council}->{id};
- add_row( \%problem, $_, \%fixed, \%open );
+ add_row( \%problem, $_, \%fixed, \%open, \@pins );
}
}
}
- $c->stash->{fixed} = \%fixed;
- $c->stash->{open} = \%open;
+ $c->stash(
+ fixed => \%fixed,
+ open => \%open,
+ pins => \@pins,
+ );
return 1;
}
@@ -348,7 +377,7 @@ sub redirect_area : Private {
my $fourweeks = 4*7*24*60*60;
sub add_row {
- my ( $problem, $council, $fixed, $open ) = @_;
+ my ( $problem, $council, $fixed, $open, $pins ) = @_;
my $duration_str = ( $problem->{duration} > 2 * $fourweeks ) ? 'old' : 'new';
my $type = ( $problem->{duration} > 2 * $fourweeks )
? 'unknown'
@@ -357,6 +386,14 @@ sub add_row {
push @{$fixed->{$council}{$duration_str}}, $problem if $problem->{state} eq 'fixed';
# Open problems are either unknown, older, or new
push @{$open->{$council}{$type}}, $problem if $problem->{state} eq 'confirmed';
+
+ push @$pins, {
+ latitude => $problem->{latitude},
+ longitude => $problem->{longitude},
+ colour => $problem->{state} eq 'fixed' ? 'green' : 'red',
+ id => $problem->{id},
+ title => $problem->{title},
+ };
}
=head1 AUTHOR
diff --git a/templates/web/default/maps/openlayers.html b/templates/web/default/maps/openlayers.html
index e5b1a6792..45551c3d5 100644
--- a/templates/web/default/maps/openlayers.html
+++ b/templates/web/default/maps/openlayers.html
@@ -8,6 +8,7 @@
<script type="text/javascript">
var fixmystreet = {
'page': '[% page %]',
+ 'area': '[% map.area %]',
'all_pins': [% all_pins || "''" | html %],
'latitude': [% map.latitude %],
'longitude': [% map.longitude %],
diff --git a/templates/web/default/reports/council.html b/templates/web/default/reports/council.html
index 1c35481e7..d2578f9f2 100755
--- a/templates/web/default/reports/council.html
+++ b/templates/web/default/reports/council.html
@@ -8,12 +8,29 @@
%]
[% END %]
-[% INCLUDE 'header.html',
+[%
+ PROCESS "maps/${map.type}.html";
+ INCLUDE 'header.html',
title = tprintf(loc('%s - Summary reports'), name)
context = 'reports'
rss = [ tprintf(loc('Problems within %s, FixMyStreet'), name), rss_url ]
%]
+[% map_html %]
+
+[% IF children %]
+<h2 style="clear:right">[% loc('Wards of this council') %]</h2>
+<p>[% loc('Follow a ward link to view only reports within that ward.') %]</p>
+<ul>
+[% FOR c IN children.values.sort('name') %]
+<li><a href="[% c.url %]">[% c.name %]</a></p>
+[% END %]
+</ul>
+[% END %]
+
+</div>
+<div id="side">
+
<p><a href="[% rss_url %]"><img align="right" src="/i/feed.png" width="16" height="16" title="[% loc('RSS feed') %]" alt="[% tprintf(loc('RSS feed of problems in this %s'), thing) %]" border="0" hspace="4"></a>
[% IF c.cobrand.all_councils_report %]
@@ -22,24 +39,21 @@
[% tprintf( loc('This is a summary of all reports for this %s.'), thing ) %]
[% END %]
-[%# FIXME: It should link to council from a ward page, and should have list of wards on a council page. And a map?
- The reason c.req.base/path is used below is that passing undef to uri_with
- in a template actually passes "", and so the key still appears in the URL.
-%]
-
-[% IF c.req.parameters.all AND !c.cobrand.all_councils_report %]
- [% tprintf( loc('You can <a href="%s">see less detail</a>.'), c.req.base _ c.req.path ) %]
-[% ELSIF !c.cobrand.all_councils_report %]
- [% tprintf( loc('You can <a href="%s">see more details</a>.'), c.req.uri_with( { all = 1 } ) ) %]
-[% ELSIF c.req.parameters.all %]
- [% tprintf( loc('You can <a href="%s">see less detail</a> or go back and <a href="/reports">show all councils</a>.'), c.req.base _ c.req.path ) %]
+[% IF ward %]
+[% tprintf( loc('You can <a href="%s">view all reports for the council</a> or <a href="/reports">show all councils</a>.'), council_url ) %]
[% ELSE %]
- [% tprintf( loc('You can <a href="%s">see more details</a> or go back and <a href="/reports">show all councils</a>.'), c.req.uri_with( { all = 1 } ) ) %]
+[% loc('You can <a href="/reports">show all councils</a>.') %]
[% END %]
<h2>[% name %]</h2>
-<div id="col_problems">
+ [% INCLUDE 'pagination' %]
+
+ [% INCLUDE column
+ title = loc('Recently fixed')
+ problems = fixed.${council.id}.new
+ %]
+
[% INCLUDE column
title = loc('New problems')
problems = open.${council.id}.new
@@ -62,19 +76,13 @@
problems = open.${council.id}.unknown
%]
[% END %]
-</div>
-<div id="col_fixed">
- [% INCLUDE column
- title = loc('Recently fixed')
- problems = fixed.${council.id}.new
- %]
[% INCLUDE column
title = loc('Old fixed')
problems = fixed.${council.id}.old
%]
-</div>
+</div>
[% INCLUDE 'footer.html' %]
[% BLOCK column %]
@@ -89,7 +97,6 @@
[% IF c.cobrand.moniker != 'emptyhomes' %]
[% IF problem.councils == 0 %] <small>[% loc('(not sent to council)') %]</small> [% END %]
[% END %]
- [% IF all %] <br><small>[% problem.detail %]</small> [% END %]
</li>
[% END %]
</ul>
@@ -97,3 +104,23 @@
[% END %]
[% END %]
+[% BLOCK pagination %]
+ [% IF pager.last_page > 1 %]
+ <p>
+ [% IF pager.previous_page %]
+ <a href="[% c.req.uri_with({'p' => pager.previous_page}) %]">&larr; Previous</a>
+ [% ELSE %]
+ &larr; Previous
+ [% END %]
+ |
+ [% pager.first %] to [% pager.last %] of [% pager.total_entries %]
+ |
+ [% IF pager.next_page %]
+ <a href="[% c.req.uri_with({'p' => pager.next_page}) %]">Next &rarr;</a>
+ [% ELSE %]
+ Next &rarr;
+ [% END %]
+ </p>
+ [% END %]
+[% END %]
+
diff --git a/web/js/map-OpenLayers.js b/web/js/map-OpenLayers.js
index 4a7d3b97e..821bbafc3 100644
--- a/web/js/map-OpenLayers.js
+++ b/web/js/map-OpenLayers.js
@@ -41,6 +41,21 @@ YAHOO.util.Event.onContentReady('map', function() {
return false;
});
+ if ( fixmystreet.area ) {
+ var area = new OpenLayers.Layer.Vector("KML", {
+ strategies: [ new OpenLayers.Strategy.Fixed() ],
+ protocol: new OpenLayers.Protocol.HTTP({
+ url: "/mapit/area/" + fixmystreet.area + ".kml",
+ format: new OpenLayers.Format.KML()
+ })
+ });
+ fixmystreet.map.addLayer(area);
+ area.events.register('loadend', null, function(a,b,c) {
+ var bounds = area.getDataExtent();
+ if (bounds) { fixmystreet.map.zoomToExtent( bounds ); }
+ });
+ }
+
var pin_layer_options = {
styleMap: new OpenLayers.StyleMap({
'default': new OpenLayers.Style({
@@ -78,7 +93,8 @@ YAHOO.util.Event.onContentReady('map', function() {
fixmystreet.map.addLayer(fixmystreet.markers);
if ( fixmystreet.zoomToBounds ) {
- fixmystreet.map.zoomToExtent( fixmystreet.markers.getDataExtent() );
+ var bounds = fixmystreet.markers.getDataExtent();
+ if (bounds) { fixmystreet.map.zoomToExtent( bounds ); }
}
});