diff options
31 files changed, 613 insertions, 144 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index baf561ebc..054564646 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,12 +6,19 @@ using confirmation by phone text. - Improved email/phone management in your profile. - Area summary statistics page in admin #1834 + - Allow multiple wards to be shown on reports page + - Don't cover whole map with pin loading indicator. + - Add Expand map toggle to more mobile maps. - Bugfixes - Shortlist menu item always remains a link #1855 - Fix encoded entities in RSS output. #1859 + - Only save category changes if staff user update valid #1857 + - Only create one update when staff user updating category #1857 + - Do not include blank updates in email alerts #1857 - Admin improvements: - Character length limit can be placed on report detailed information #1848 - Inspector panel shows nearest address if available #1850 + - Return a 200 rather than 404 for ref ID lookup. * v2.2 (13th September 2017) - New features: diff --git a/perllib/FixMyStreet/App/Controller/Admin.pm b/perllib/FixMyStreet/App/Controller/Admin.pm index 0caa25710..719b04cf6 100644 --- a/perllib/FixMyStreet/App/Controller/Admin.pm +++ b/perllib/FixMyStreet/App/Controller/Admin.pm @@ -797,6 +797,19 @@ sub reports : Path('reports') { } +sub update_user : Private { + my ($self, $c, $object) = @_; + my $parsed = FixMyStreet::SMS->parse_username($c->get_param('username')); + if ($parsed->{email} || ($parsed->{phone} && $parsed->{may_be_mobile})) { + my $user = $c->model('DB::User')->find_or_create({ $parsed->{type} => $parsed->{username} }); + if ($user->id && $user->id != $object->user->id) { + $object->user( $user ); + return 1; + } + } + return 0; +} + sub report_edit : Path('report_edit') : Args(1) { my ( $self, $c, $id ) = @_; @@ -901,14 +914,7 @@ sub report_edit : Path('report_edit') : Args(1) { $problem->set_inflated_columns(\%columns); $c->forward( '/admin/report_edit_category', [ $problem ] ); - - my $parsed = FixMyStreet::SMS->parse_username($c->get_param('username')); - if ($parsed->{email} || ($parsed->{phone} && $parsed->{phone}->is_mobile)) { - my $user = $c->model('DB::User')->find_or_create({ $parsed->{type} => $parsed->{username} }); - if ($user->id && $user->id != $problem->user->id) { - $problem->user( $user ); - } - } + $c->forward('update_user', [ $problem ]); # Deal with photos my $remove_photo_param = $self->_get_remove_photo_param($c); @@ -950,7 +956,7 @@ Handles changing a problem's category and the complexity that comes with it. =cut sub report_edit_category : Private { - my ($self, $c, $problem) = @_; + my ($self, $c, $problem, $no_comment) = @_; if ((my $category = $c->get_param('category')) ne $problem->category) { my $category_old = $problem->category; @@ -978,16 +984,21 @@ sub report_edit_category : Private { } $problem->bodies_str(join( ',', @new_body_ids )); - $problem->add_to_comments({ - text => '*' . sprintf(_('Category changed from ‘%s’ to ‘%s’'), $category_old, $category) . '*', - created => \'current_timestamp', - confirmed => \'current_timestamp', - user_id => $c->user->id, - name => $c->user->from_body ? $c->user->from_body->name : $c->user->name, - state => 'confirmed', - mark_fixed => 0, - anonymous => 0, - }); + my $update_text = '*' . sprintf(_('Category changed from ‘%s’ to ‘%s’'), $category_old, $category) . '*'; + if ($no_comment) { + $c->stash->{update_text} = $update_text; + } else { + $problem->add_to_comments({ + text => $update_text, + created => \'current_timestamp', + confirmed => \'current_timestamp', + user_id => $c->user->id, + name => $c->user->from_body ? $c->user->from_body->name : $c->user->name, + state => 'confirmed', + mark_fixed => 0, + anonymous => 0, + }); + } } } @@ -1251,14 +1262,7 @@ sub update_edit : Path('update_edit') : Args(1) { $update->anonymous( $c->get_param('anonymous') ); $update->state( $new_state ); - my $parsed = FixMyStreet::SMS->parse_username($c->get_param('username')); - if ($parsed->{email} || ($parsed->{phone} && $parsed->{phone}->is_mobile)) { - my $user = $c->model('DB::User')->find_or_create({ $parsed->{type} => $parsed->{username} }); - if ($user->id && $user->id != $update->user->id) { - $edited = 1; - $update->user( $user ); - } - } + $edited = 1 if $c->forward('update_user', [ $update ]); if ( $new_state eq 'confirmed' and $old_state eq 'unconfirmed' ) { $update->confirmed( \'current_timestamp' ); @@ -1298,6 +1302,18 @@ sub update_edit : Path('update_edit') : Args(1) { return 1; } +sub phone_check : Private { + my ($self, $c, $phone) = @_; + my $parsed = FixMyStreet::SMS->parse_username($phone); + if ($parsed->{phone} && $parsed->{may_be_mobile}) { + return $parsed->{username}; + } elsif ($parsed->{phone}) { + $c->stash->{field_errors}->{phone} = _('Please enter a mobile number'); + } else { + $c->stash->{field_errors}->{phone} = _('Please check your phone number is correct'); + } +} + sub user_add : Path('user_edit') : Args(0) { my ( $self, $c ) = @_; @@ -1329,14 +1345,8 @@ sub user_add : Path('user_edit') : Args(0) { } if ($phone_v) { - my $parsed = FixMyStreet::SMS->parse_username($phone); - if ($parsed->{phone} && $parsed->{phone}->is_mobile) { - $phone = $parsed->{username}; - } elsif ($parsed->{phone}) { - $c->stash->{field_errors}->{phone} = _('Please enter a mobile number'); - } else { - $c->stash->{field_errors}->{phone} = _('Please check your phone number is correct'); - } + my $parsed_phone = $c->forward('phone_check', [ $phone ]); + $phone = $parsed_phone if $parsed_phone; } my $existing_email = $email_v && $c->model('DB::User')->find( { email => $email } ); @@ -1417,14 +1427,8 @@ sub user_edit : Path('user_edit') : Args(1) { } if ($phone_v) { - my $parsed = FixMyStreet::SMS->parse_username($phone); - if ($parsed->{phone} && $parsed->{phone}->is_mobile) { - $phone = $parsed->{username}; - } elsif ($parsed->{phone}) { - $c->stash->{field_errors}->{phone} = _('Please enter a mobile number'); - } else { - $c->stash->{field_errors}->{phone} = _('Please check your phone number is correct'); - } + my $parsed_phone = $c->forward('phone_check', [ $phone ]); + $phone = $parsed_phone if $parsed_phone; } unless ($user->name) { diff --git a/perllib/FixMyStreet/App/Controller/Admin/AreaStats.pm b/perllib/FixMyStreet/App/Controller/Admin/AreaStats.pm index 932631cba..2058ea872 100644 --- a/perllib/FixMyStreet/App/Controller/Admin/AreaStats.pm +++ b/perllib/FixMyStreet/App/Controller/Admin/AreaStats.pm @@ -78,6 +78,8 @@ sub stats : Private { my ($self, $c) = @_; my $date = DateTime->now->subtract(days => 30); + # set it to midnight so we get consistent result through the day + $date->truncate( to => 'day' ); $c->forward('/admin/fetch_contacts'); @@ -145,21 +147,21 @@ sub stats : Private { my $comments = $c->model('DB::Comment')->to_body( $c->stash->{body} )->search( - $params, { - join => 'problem' + %$params, + 'me.id' => { 'in' => \"(select min(id) from comment where me.problem_id=comment.problem_id and problem_state not in ('', 'confirmed') group by problem_state)" }, + }, + { + join => 'problem', + group_by => [ 'problem_state' ], + select => [ 'problem_state', { count => 'me.id' } ], + as => [ qw/problem_state state_count/ ], } ); - # you can have multiple comments with the same problem state so need to only count - # one instance. - my %state_seen = (); while (my $comment = $comments->next) { my $meta_state = $state_map->{$comment->problem_state}; - my $key = $comment->problem->id . "-$meta_state"; - next if $state_seen{$key}; - $c->stash->{$meta_state} += 1; - $state_seen{$key} = 1; + $c->stash->{$meta_state} += $comment->get_column('state_count'); } $params = { @@ -205,7 +207,12 @@ sub stats : Private { join => 'problem' } )->first; - $c->stash->{average} = int( ($comments->get_column('time')||0)/ 60 / 60 / 24 + 0.5 ); + my $raw_average = $comments->get_column('time'); + if (defined $raw_average) { + $c->stash->{average} = int( $raw_average / 60 / 60 / 24 + 0.5 ); + } else { + $c->stash->{average} = -1; + } } sub load_user_body : Private { diff --git a/perllib/FixMyStreet/App/Controller/Around.pm b/perllib/FixMyStreet/App/Controller/Around.pm index 44ccb5259..6af780c35 100644 --- a/perllib/FixMyStreet/App/Controller/Around.pm +++ b/perllib/FixMyStreet/App/Controller/Around.pm @@ -8,6 +8,7 @@ use FixMyStreet::Map; use Encode; use JSON::MaybeXS; use Utils; +use Try::Tiny; =head1 NAME @@ -364,13 +365,17 @@ sub lookup_by_ref : Private { external_id => $ref ]); - if ( $problems->count == 0) { - $c->detach( '/page_error_404_not_found', [] ); - } elsif ( $problems->count == 1 ) { - $c->res->redirect( $c->uri_for( '/report', $problems->first->id ) ); - } else { + my $count = try { + $problems->count; + } catch { + 0; + }; + + if ($count > 1) { $c->stash->{ref} = $ref; $c->stash->{matching_reports} = [ $problems->all ]; + } elsif ($count == 1) { + $c->res->redirect( $c->uri_for( '/report', $problems->first->id ) ); } } diff --git a/perllib/FixMyStreet/App/Controller/Auth.pm b/perllib/FixMyStreet/App/Controller/Auth.pm index b453f593b..80e407147 100644 --- a/perllib/FixMyStreet/App/Controller/Auth.pm +++ b/perllib/FixMyStreet/App/Controller/Auth.pm @@ -119,7 +119,7 @@ sub code_sign_in : Private { my $parsed = FixMyStreet::SMS->parse_username($username); if ($parsed->{type} eq 'phone' && FixMyStreet->config('SMS_AUTHENTICATION')) { - $c->forward('phone/sign_in', [ $parsed->{phone} ]); + $c->forward('phone/sign_in', [ $parsed ]); } else { $c->forward('email_sign_in', [ $parsed->{username} ]); } diff --git a/perllib/FixMyStreet/App/Controller/Auth/Phone.pm b/perllib/FixMyStreet/App/Controller/Auth/Phone.pm index 4e9f92596..e4ffc2205 100644 --- a/perllib/FixMyStreet/App/Controller/Auth/Phone.pm +++ b/perllib/FixMyStreet/App/Controller/Auth/Phone.pm @@ -45,19 +45,19 @@ and sets up the token/etc to deal with the response. =cut sub sign_in : Private { - my ( $self, $c, $phone ) = @_; + my ( $self, $c, $parsed ) = @_; - unless ($phone) { + unless ($parsed->{phone}) { $c->stash->{username_error} = 'other_phone'; return; } - unless ($phone->is_mobile) { + unless ($parsed->{may_be_mobile}) { $c->stash->{username_error} = 'nonmobile'; return; } - (my $number = $phone->format) =~ s/\s+//g; + (my $number = $parsed->{phone}->format) =~ s/\s+//g; if ( FixMyStreet->config('SIGNUPS_DISABLED') && !$c->model('DB::User')->find({ phone => $number }) diff --git a/perllib/FixMyStreet/App/Controller/Auth/Profile.pm b/perllib/FixMyStreet/App/Controller/Auth/Profile.pm index ecf009150..acffd3019 100644 --- a/perllib/FixMyStreet/App/Controller/Auth/Profile.pm +++ b/perllib/FixMyStreet/App/Controller/Auth/Profile.pm @@ -118,14 +118,14 @@ sub change_phone : Path('/auth/change_phone') { # If we've not used a mobile and we're not specifically verifying, # and phone isn't our only verified way of logging in, # then allow change of number (for e.g. landline). - if (!FixMyStreet->config('SMS_AUTHENTICATION') || (!$parsed->{phone}->is_mobile && !$c->stash->{verifying} && $c->user->email_verified)) { + if (!FixMyStreet->config('SMS_AUTHENTICATION') || (!$parsed->{may_be_mobile} && !$c->stash->{verifying} && $c->user->email_verified)) { $c->user->update({ phone => $phone, phone_verified => 0 }); $c->flash->{flash_message} = _('You have successfully added your phone number.'); $c->res->redirect('/my'); $c->detach; } - $c->forward('/auth/phone/sign_in', [ $parsed->{phone} ]); + $c->forward('/auth/phone/sign_in', [ $parsed ]); } sub verify_item : Path('/auth/verify') : Args(1) { diff --git a/perllib/FixMyStreet/App/Controller/Report.pm b/perllib/FixMyStreet/App/Controller/Report.pm index ba9fa11b9..c72c75d3a 100644 --- a/perllib/FixMyStreet/App/Controller/Report.pm +++ b/perllib/FixMyStreet/App/Controller/Report.pm @@ -424,7 +424,11 @@ sub inspect : Private { } if ($permissions->{report_inspect} || $permissions->{report_edit_category}) { - $c->forward( '/admin/report_edit_category', [ $problem ] ); + $c->forward( '/admin/report_edit_category', [ $problem, 1 ] ); + + if ($c->stash->{update_text}) { + $update_text .= "\n\n" . $c->stash->{update_text}; + } # The new category might require extra metadata (e.g. pothole size), so # we need to update the problem with the new values. diff --git a/perllib/FixMyStreet/App/Controller/Reports.pm b/perllib/FixMyStreet/App/Controller/Reports.pm index 8f8205719..187dfb299 100644 --- a/perllib/FixMyStreet/App/Controller/Reports.pm +++ b/perllib/FixMyStreet/App/Controller/Reports.pm @@ -131,9 +131,10 @@ sub ward : Path : Args(2) { $c->forward('/auth/get_csrf_token'); + my @wards = split /\|/, $ward || ""; $c->forward( 'body_check', [ $body ] ); - $c->forward( 'ward_check', [ $ward ] ) - if $ward; + $c->forward( 'ward_check', [ @wards ] ) + if @wards; $c->forward( 'check_canonical_url', [ $body ] ); $c->forward( 'stash_report_filter_status' ); $c->forward( 'load_and_group_problems' ); @@ -166,7 +167,7 @@ sub ward : Path : Args(2) { my %map_params = ( latitude => @$pins ? $pins->[0]{latitude} : 0, longitude => @$pins ? $pins->[0]{longitude} : 0, - area => $c->stash->{ward} ? $c->stash->{ward}->{id} : [ keys %{$c->stash->{body}->areas} ], + area => [ $c->stash->{wards} ? map { $_->{id} } @{$c->stash->{wards}} : keys %{$c->stash->{body}->areas} ], any_zoom => 1, ); FixMyStreet::Map::display_map( @@ -176,7 +177,7 @@ sub ward : Path : Args(2) { $c->cobrand->tweak_all_reports_map( $c ); # List of wards - if ( !$c->stash->{ward} && $c->stash->{body}->id && $c->stash->{body}->body_areas->first ) { + if ( !$c->stash->{wards} && $c->stash->{body}->id && $c->stash->{body}->body_areas->first ) { my $children = mySociety::MaPit::call('area/children', [ $c->stash->{body}->body_areas->first->area_id ], type => $c->cobrand->area_types_children, ); @@ -343,18 +344,20 @@ sub body_check : Private { =head2 ward_check -This action checks the ward name from a URI exists and is part of the right +This action checks the ward names from a URI exists and are part of the right parent, already found with body_check. It either stores the ward Area if okay, or redirects to the body page if bad. =cut sub ward_check : Private { - my ( $self, $c, $ward ) = @_; + my ( $self, $c, @wards ) = @_; - $ward =~ s/\+/ /g; - $ward =~ s/\.html//; - $ward =~ s{_}{/}g; + foreach (@wards) { + s/\+/ /g; + s/\.html//; + s{_}{/}g; + } # Could be from RSS area, or body... my $parent_id; @@ -366,15 +369,20 @@ sub ward_check : Private { $parent_id = $c->stash->{area}->{id}; } - my $qw = mySociety::MaPit::call('areas', $ward, + my $qw = mySociety::MaPit::call('area/children', [ $parent_id ], type => $c->cobrand->area_types_children, ); + my %names = map { $_ => 1 } @wards; + my @areas; foreach my $area (sort { $a->{name} cmp $b->{name} } values %$qw) { - if ($area->{parent_area} == $parent_id) { - $c->stash->{ward} = $area; - return; - } + push @areas, $area if $names{$area->{name}}; + } + if (@areas) { + $c->stash->{ward} = $areas[0] if @areas == 1; + $c->stash->{wards} = \@areas; + return; } + # Given a false ward name $c->stash->{body} = $c->stash->{area} unless $c->stash->{body}; @@ -448,8 +456,10 @@ sub load_and_group_problems : Private { my $problems = $c->cobrand->problems; - if ($c->stash->{ward}) { - $where->{areas} = { 'like', '%,' . $c->stash->{ward}->{id} . ',%' }; + if ($c->stash->{wards}) { + $where->{areas} = [ + map { { 'like', '%,' . $_->{id} . ',%' } } @{$c->stash->{wards}} + ]; $problems = $problems->to_body($c->stash->{body}); } elsif ($c->stash->{body}) { $problems = $problems->to_body($c->stash->{body}); @@ -510,8 +520,8 @@ sub redirect_body : Private { $url .= "/rss" if $c->stash->{rss}; $url .= '/reports'; $url .= '/' . $c->cobrand->short_name( $c->stash->{body} ); - $url .= '/' . $c->cobrand->short_name( $c->stash->{ward} ) - if $c->stash->{ward}; + $url .= '/' . join('|', map { $c->cobrand->short_name($_) } @{$c->stash->{wards}}) + if $c->stash->{wards}; $c->res->redirect( $c->uri_for($url, $c->req->params ) ); } diff --git a/perllib/FixMyStreet/DB/Result/Comment.pm b/perllib/FixMyStreet/DB/Result/Comment.pm index 562f29693..409a6e1ab 100644 --- a/perllib/FixMyStreet/DB/Result/Comment.pm +++ b/perllib/FixMyStreet/DB/Result/Comment.pm @@ -274,14 +274,9 @@ sub problem_state_display { return FixMyStreet::DB->resultset("State")->display('confirmed', 1); } elsif ($self->problem_state) { my $state = $self->problem_state; - if ($state eq 'not responsible') { - $update_state = _( "not the council's responsibility" ); - if ($cobrand eq 'bromley' || $self->problem->to_body_named('Bromley')) { - $update_state = 'third party responsibility'; - } - } else { - $update_state = FixMyStreet::DB->resultset("State")->display($state, 1); - } + 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); } return $update_state; diff --git a/perllib/FixMyStreet/DB/Result/User.pm b/perllib/FixMyStreet/DB/Result/User.pm index 296cf997d..d02039ac3 100644 --- a/perllib/FixMyStreet/DB/Result/User.pm +++ b/perllib/FixMyStreet/DB/Result/User.pm @@ -196,7 +196,7 @@ sub check_for_errors { my $parsed = FixMyStreet::SMS->parse_username($self->phone); if (!$parsed->{phone}) { $errors{username} = _('Please check your phone number is correct'); - } elsif (!$parsed->{phone}->is_mobile) { + } elsif (!$parsed->{may_be_mobile}) { $errors{username} = _('Please enter a mobile number'); } } diff --git a/perllib/FixMyStreet/DB/ResultSet/State.pm b/perllib/FixMyStreet/DB/ResultSet/State.pm index de56c738c..3e6169aeb 100644 --- a/perllib/FixMyStreet/DB/ResultSet/State.pm +++ b/perllib/FixMyStreet/DB/ResultSet/State.pm @@ -58,7 +58,7 @@ sub fixed { [ $_[0]->_filter(sub { $_->type eq 'fixed' }) ] } # This function can be used to return that label's display name. sub display { - my ($rs, $label, $single_fixed) = @_; + my ($rs, $label, $single_fixed, $cobrand) = @_; my $unchanging = { unconfirmed => _("Unconfirmed"), hidden => _("Hidden"), @@ -72,6 +72,10 @@ sub display { }; $label = 'fixed' if $single_fixed && $label =~ /^fixed - (council|user)$/; return $unchanging->{$label} if $unchanging->{$label}; + if ($cobrand && $label eq 'not responsible') { + return 'third party responsibility' if $cobrand eq 'bromley'; + return _("not the council's responsibility"); + } my ($state) = $rs->_filter(sub { $_->label eq $label }); return $label unless $state; $state->name($translate_now->{$label}) if $translate_now->{$label}; diff --git a/perllib/FixMyStreet/SMS.pm b/perllib/FixMyStreet/SMS.pm index ec9251a1a..c71cceadc 100644 --- a/perllib/FixMyStreet/SMS.pm +++ b/perllib/FixMyStreet/SMS.pm @@ -94,15 +94,19 @@ sub parse_username { } }; + my $may_be_mobile = 0; if ($phone) { $type = 'phone'; # Store phone without spaces ($username = $phone->format) =~ s/\s+//g; + # Is this mobile definitely or possibly a mobile? (+1 numbers) + $may_be_mobile = 1 if $phone->is_mobile || (!defined $phone->is_mobile && $phone->is_geographic); } return { type => $type, phone => $phone, + may_be_mobile => $may_be_mobile, username => $username, }; } diff --git a/perllib/FixMyStreet/Script/Alerts.pm b/perllib/FixMyStreet/Script/Alerts.pm index 86f11c7b5..4b5641f9e 100644 --- a/perllib/FixMyStreet/Script/Alerts.pm +++ b/perllib/FixMyStreet/Script/Alerts.pm @@ -39,6 +39,7 @@ sub send() { $item_table.name as item_name, $item_table.anonymous as item_anonymous, $item_table.confirmed as item_confirmed, $item_table.photo as item_photo, + $item_table.problem_state as item_problem_state, $head_table.* from alert, $item_table, $head_table where alert.parameter::integer = $head_table.id @@ -65,6 +66,7 @@ sub send() { $query = FixMyStreet::DB->schema->storage->dbh->prepare($query); $query->execute(); my $last_alert_id; + my $last_problem_state = ''; my %data = ( template => $alert_type->template, data => [], schema => $schema ); while (my $row = $query->fetchrow_hashref) { @@ -86,7 +88,26 @@ sub send() { alert_id => $row->{alert_id}, parameter => $row->{item_id}, } ); + + # this is currently only for new_updates + if (defined($row->{item_text})) { + # this might throw up the odd false positive but only in cases where the + # state has changed and there was already update text + if ($row->{item_problem_state} && + !( $last_problem_state eq '' && $row->{item_problem_state} eq 'confirmed' ) && + $last_problem_state ne $row->{item_problem_state} + ) { + my $state = FixMyStreet::DB->resultset("State")->display($row->{item_problem_state}, 1, $cobrand); + + my $update = _('State changed to:') . ' ' . $state; + $row->{item_text} = $row->{item_text} ? $row->{item_text} . "\n\n" . $update : + $update; + } + next unless $row->{item_text}; + } + if ($last_alert_id && $last_alert_id != $row->{alert_id}) { + $last_problem_state = ''; _send_aggregated_alert_email(%data); %data = ( template => $alert_type->template, data => [], schema => $schema ); } diff --git a/t/Mock/MapIt.pm b/t/Mock/MapIt.pm index 6e3c5d673..8dd10c53d 100644 --- a/t/Mock/MapIt.pm +++ b/t/Mock/MapIt.pm @@ -81,10 +81,6 @@ sub dispatch_request { $self->output({2226 => {parent_area => undef, id => 2226, name => "Gloucestershire County Council", type => "CTY"}}); } elsif ($areas eq 'Cheltenham') { $self->output({2326 => {parent_area => undef, id => 2326, name => "Cheltenham Borough Council", type => "DIS"}}); - } elsif ($areas eq 'Lansdown and Park') { - $self->output({22261 => {parent_area => 2226, id => 22261, name => "Lansdown and Park", type => "CED"}}); - } elsif ($areas eq 'Lansdown') { - $self->output({23261 => {parent_area => 2326, id => 23261, name => "Lansdown", type => "DIW"}}); } elsif ($areas eq 'UTA') { $self->output({2650 => {parent_area => undef, id => 2650, name => "Aberdeen Council", type => "UTA"}}); } @@ -104,6 +100,18 @@ sub dispatch_request { sub (GET + /area/*/children) { my ($self, $area) = @_; + if ($area eq '2514') { + return $self->output({ + 8794 => {parent_area => 2514, id => 8794, name => "Aston", type => "MTW"}, + 8773 => {parent_area => 2514, id => 8773, name => "Bournville", type => "MTW"}, + }); + } + if ($area eq '2326') { + return $self->output({23261 => {parent_area => 2326, id => 23261, name => "Lansdown", type => "DIW"}}); + } + if ($area eq '2226') { + return $self->output({22261 => {parent_area => 2226, id => 22261, name => "Lansdown and Park", type => "CED"}}); + } my $response = { "60705" => { "parent_area" => 2245, "generation_high" => 25, "all_names" => { }, "id" => 60705, "codes" => { "ons" => "00HY226", "gss" => "E04011842", "unit_id" => "17101" }, "name" => "Trowbridge", "country" => "E", "type_name" => "Civil parish/community", "generation_low" => 12, "country_name" => "England", "type" => "CPC" }, "62883" => { "parent_area" => 2245, "generation_high" => 25, "all_names" => { }, "id" => 62883, "codes" => { "ons" => "00HY026", "gss" => "E04011642", "unit_id" => "17205" }, "name" => "Bradford-on-Avon", "country" => "E", "type_name" => "Civil parish/community", "generation_low" => 12, "country_name" => "England", "type" => "CPC" }, diff --git a/t/app/controller/alert_new.t b/t/app/controller/alert_new.t index 97a19b3b8..4e8fd1b29 100644 --- a/t/app/controller/alert_new.t +++ b/t/app/controller/alert_new.t @@ -475,7 +475,7 @@ subtest "Test normal alert signups and that alerts are sent" => sub { $mech->delete_user($user2); }; -subtest "Test alerts are correct for no-text updates" => sub { +subtest "Test alerts are not sent for no-text updates" => sub { $mech->delete_user( 'reporter@example.com' ); $mech->delete_user( 'alerts@example.com' ); @@ -513,6 +513,40 @@ subtest "Test alerts are correct for no-text updates" => sub { my $report_id = $report->id; ok $report, "created test report - $report_id"; + my $report2 = FixMyStreet::App->model('DB::Problem')->create( { + postcode => 'EH1 1BB', + bodies_str => '1', + areas => ',11808,135007,14419,134935,2651,20728,', + category => 'Street lighting', + title => 'Testing', + detail => 'Testing Detail', + used_map => 1, + name => $user1->name, + anonymous => 0, + state => 'fixed - user', + confirmed => $dt_parser->format_datetime($dt), + lastupdate => $dt_parser->format_datetime($dt), + whensent => $dt_parser->format_datetime($dt->clone->add( minutes => 5 )), + lang => 'en-gb', + service => '', + cobrand => 'default', + cobrand_data => '', + send_questionnaire => 1, + latitude => '55.951963', + longitude => '-3.189944', + user_id => $user1->id, + } ); + my $report2_id = $report2->id; + ok $report2, "created test report - $report2_id"; + + # Must be first + my $alert2 = FixMyStreet::App->model('DB::Alert')->create( { + parameter => $report2_id, + alert_type => 'new_updates', + user => $user2, + } )->confirm; + ok $alert2, 'created alert for other user'; + my $alert = FixMyStreet::App->model('DB::Alert')->create( { parameter => $report_id, alert_type => 'new_updates', @@ -533,6 +567,92 @@ subtest "Test alerts are correct for no-text updates" => sub { my $update_id = $update->id; ok $update, "created test update from staff user - $update_id"; + my $update2 = FixMyStreet::App->model('DB::Comment')->create( { + problem_id => $report2_id, + user_id => $user3->id, + name => 'Staff User', + mark_fixed => 'false', + text => 'This is a normal update', + state => 'confirmed', + confirmed => $dt->clone->add( hours => 9 ), + anonymous => 'f', + } ); + my $update2_id = $update2->id; + ok $update2, "created test update from staff user - $update2_id"; + + $mech->clear_emails_ok; + FixMyStreet::override_config { + MAPIT_URL => 'http://mapit.uk/', + }, sub { + FixMyStreet::Script::Alerts::send(); + }; + + $mech->email_count_is(1); + + $mech->delete_user($user1); + $mech->delete_user($user2); + $mech->delete_user($user3); +}; + +subtest "Test no marked as confirmed added to alerts" => sub { + $mech->delete_user( 'reporter@example.com' ); + $mech->delete_user( 'alerts@example.com' ); + + my $user1 = $mech->create_user_ok('reporter@example.com', name => 'Reporter User' ); + my $user2 = $mech->create_user_ok('alerts@example.com', name => 'Alert User' ); + my $user3 = $mech->create_user_ok('staff@example.com', name => 'Staff User', from_body => $gloucester ); + my $dt = DateTime->now(time_zone => 'Europe/London')->add(days => 2); + + my $dt_parser = FixMyStreet::App->model('DB')->schema->storage->datetime_parser; + + my $report_time = '2011-03-01 12:00:00'; + my $report = FixMyStreet::App->model('DB::Problem')->find_or_create( { + postcode => 'EH1 1BB', + bodies_str => '1', + areas => ',11808,135007,14419,134935,2651,20728,', + category => 'Street lighting', + title => 'Testing', + detail => 'Testing Detail', + used_map => 1, + name => $user1->name, + anonymous => 0, + state => 'confirmed', + confirmed => $dt_parser->format_datetime($dt), + lastupdate => $dt_parser->format_datetime($dt), + whensent => $dt_parser->format_datetime($dt->clone->add( minutes => 5 )), + lang => 'en-gb', + service => '', + cobrand => 'default', + cobrand_data => '', + send_questionnaire => 1, + latitude => '55.951963', + longitude => '-3.189944', + user_id => $user1->id, + } ); + my $report_id = $report->id; + ok $report, "created test report - $report_id"; + + my $alert = FixMyStreet::App->model('DB::Alert')->create( { + parameter => $report_id, + alert_type => 'new_updates', + user => $user2, + } )->confirm; + ok $alert, 'created alert for other user'; + + my $update = FixMyStreet::App->model('DB::Comment')->create( { + problem_id => $report_id, + user_id => $user3->id, + name => 'Staff User', + mark_fixed => 'false', + text => 'this is update', + state => 'confirmed', + problem_state => 'confirmed', + confirmed => $dt->clone->add( hours => 9 ), + anonymous => 'f', + } ); + my $update_id = $update->id; + ok $update, "created test update from staff user - $update_id"; + $mech->clear_emails_ok; FixMyStreet::override_config { MAPIT_URL => 'http://mapit.uk/', @@ -545,15 +665,116 @@ subtest "Test alerts are correct for no-text updates" => sub { my $body = $mech->get_text_body_from_email($email); like $body, qr/The following updates have been left on this report:/, 'email is about updates to existing report'; like $body, qr/Staff User/, 'Update comes from correct user'; - - my @urls = $mech->get_link_from_email($email, 1); - is $urls[0], "http://www.example.org/report/" . $report_id, "Correct report URL in email"; + unlike $body, qr/State changed to: Open/s, 'no marked as confirmed text'; $mech->delete_user($user1); $mech->delete_user($user2); $mech->delete_user($user3); }; +for my $test ( + { + update_text => '', + problem_state => 'investigating', + expected_text => 'State changed to: Investigating', + desc => 'comment changing status included in email', + }, + { + update_text => 'Category changed to Potholes', + problem_state => '', + expected_text => 'Category changed to Potholes', + desc => 'comment about category included', + }, + { + update_text => 'Category changed to Potholes', + problem_state => 'investigating', + expected_text => 'Category changed to Potholes.*Investigating', + desc => 'comment about category and status change included', + }, +) { + subtest $test->{desc} => sub { + $mech->delete_user( 'reporter@example.com' ); + $mech->delete_user( 'alerts@example.com' ); + + my $user1 = $mech->create_user_ok('reporter@example.com', name => 'Reporter User' ); + my $user2 = $mech->create_user_ok('alerts@example.com', name => 'Alert User' ); + my $user3 = $mech->create_user_ok('staff@example.com', name => 'Staff User', from_body => $gloucester ); + my $dt = DateTime->now(time_zone => 'Europe/London')->add(days => 2); + + my $dt_parser = FixMyStreet::App->model('DB')->schema->storage->datetime_parser; + + my $report_time = '2011-03-01 12:00:00'; + my $report = FixMyStreet::App->model('DB::Problem')->find_or_create( { + postcode => 'EH1 1BB', + bodies_str => '1', + areas => ',11808,135007,14419,134935,2651,20728,', + category => 'Street lighting', + title => 'Testing', + detail => 'Testing Detail', + used_map => 1, + name => $user1->name, + anonymous => 0, + state => 'confirmed', + confirmed => $dt_parser->format_datetime($dt), + lastupdate => $dt_parser->format_datetime($dt), + whensent => $dt_parser->format_datetime($dt->clone->add( minutes => 5 )), + lang => 'en-gb', + service => '', + cobrand => 'default', + cobrand_data => '', + send_questionnaire => 1, + latitude => '55.951963', + longitude => '-3.189944', + user_id => $user1->id, + } ); + my $report_id = $report->id; + ok $report, "created test report - $report_id"; + + my $alert = FixMyStreet::App->model('DB::Alert')->create( { + parameter => $report_id, + alert_type => 'new_updates', + user => $user2, + } )->confirm; + ok $alert, 'created alert for other user'; + + my $update = FixMyStreet::App->model('DB::Comment')->create( { + problem_id => $report_id, + user_id => $user3->id, + name => 'Staff User', + mark_fixed => 'false', + text => $test->{update_text}, + problem_state => $test->{problem_state}, + state => 'confirmed', + confirmed => $dt->clone->add( hours => 9 ), + anonymous => 'f', + } ); + my $update_id = $update->id; + ok $update, "created test update from staff user - $update_id"; + + $mech->clear_emails_ok; + FixMyStreet::override_config { + MAPIT_URL => 'http://mapit.uk/', + }, sub { + FixMyStreet::Script::Alerts::send(); + }; + + $mech->email_count_is(1); + my $expected_text = $test->{expected_text}; + my $email = $mech->get_email; + my $body = $mech->get_text_body_from_email($email); + like $body, qr/The following updates have been left on this report:/, 'email is about updates to existing report'; + like $body, qr/Staff User/, 'Update comes from correct user'; + like $body, qr/$expected_text/s, 'Expected text present'; + + my @urls = $mech->get_link_from_email($email, 1); + is $urls[0], "http://www.example.org/report/" . $report_id, "Correct report URL in email"; + + $mech->delete_user($user1); + $mech->delete_user($user2); + $mech->delete_user($user3); + }; +} + subtest "Test signature template is used from cobrand" => sub { $mech->delete_user( 'reporter@example.com' ); $mech->delete_user( 'alerts@example.com' ); diff --git a/t/app/controller/area_stats.t b/t/app/controller/area_stats.t index 6ea03cabf..ce2e3d7d6 100644 --- a/t/app/controller/area_stats.t +++ b/t/app/controller/area_stats.t @@ -98,6 +98,8 @@ FixMyStreet::override_config { $mech->text_contains('Potholes6'); $mech->text_contains('Traffic lights13'); + + $mech->text_contains('average time between issue being opened and set to another status was 0 days'); }; subtest 'shows correct stats to area user' => sub { @@ -183,6 +185,17 @@ FixMyStreet::override_config { $mech->text_contains('Traffic lights3730'); }; + subtest 'ignores second state change if first was last month' => sub { + my $comment = $scheduled_problems[0]->comments->search({}, { order_by => { '-asc' => 'id' } } )->first; + $comment->update({ confirmed => DateTime->now->subtract(days => 40) }); + $mech->get_ok("/admin/areastats/$body_id?area=20720"); + + $mech->content_contains('15 opened, 6 scheduled, 3 closed, 4 fixed'); + $mech->text_contains('Potholes2004'); + $mech->text_contains('Traffic lights3730'); + $comment->update({ confirmed => DateTime->now }); + }; + subtest 'average is only to first state change' => sub { for my $i (0..4) { $scheduled_problems[$i]->comments->first->update({ confirmed => $scheduled_problems[$i]->confirmed }); @@ -201,6 +214,16 @@ FixMyStreet::override_config { $mech->get_ok("/admin/areastats/$body_id?area=20720"); $mech->text_contains('average time between issue being opened and set to another status was 4 days'); }; + + subtest 'shows no problems changed state if no average' => sub { + for my $p (@scheduled_problems, @fixed_problems, @closed_problems) { + $p->comments->delete; + } + + $mech->get_ok("/admin/areastats/$body_id?area=20720"); + $mech->text_contains('17 opened, 0 scheduled, 0 closed, 0 fixed'); + $mech->text_contains('no problems changed state'); + } }; END { diff --git a/t/app/controller/around.t b/t/app/controller/around.t index fbb4e76cd..cdaeaf363 100644 --- a/t/app/controller/around.t +++ b/t/app/controller/around.t @@ -92,15 +92,22 @@ foreach my $test ( }; } -subtest 'check non public reports are not displayed on around page' => sub { - my $params = { - postcode => 'EH1 1BB', - latitude => 55.9519637512, - longitude => -3.17492254484, - }; - my @edinburgh_problems = - $mech->create_problems_for_body( 5, 2651, 'Around page', $params ); +my @edinburgh_problems = $mech->create_problems_for_body( 5, 2651, 'Around page', { + postcode => 'EH1 1BB', + latitude => 55.9519637512, + longitude => -3.17492254484, +}); +subtest 'check lookup by reference' => sub { + $mech->get_ok('/'); + $mech->submit_form_ok( { with_fields => { pc => 'ref:12345' } }, 'bad ref'); + $mech->content_contains('Searching found no reports'); + my $id = $edinburgh_problems[0]->id; + $mech->submit_form_ok( { with_fields => { pc => "ref:$id" } }, 'good ref'); + is $mech->uri->path, "/report/$id", "redirected to report page"; +}; + +subtest 'check non public reports are not displayed on around page' => sub { $mech->get_ok('/'); FixMyStreet::override_config { ALLOWED_COBRANDS => [ { 'fixmystreet' => '.' } ], diff --git a/t/app/controller/auth_phone.t b/t/app/controller/auth_phone.t index 8673f5c62..435ea7552 100644 --- a/t/app/controller/auth_phone.t +++ b/t/app/controller/auth_phone.t @@ -47,7 +47,7 @@ subtest 'Log in using mobile, by text' => sub { }, sub { $mech->submit_form_ok({ form_name => 'general_auth', - fields => { username => '+61491570156', password_register => 'secret' }, + fields => { username => '+18165550100', password_register => 'secret' }, button => 'sign_in_by_code', }, "sign in using mobile"); @@ -61,7 +61,7 @@ subtest 'Log in using mobile, by text' => sub { with_fields => { code => $code } }, 'submit correct code'); - my $user = FixMyStreet::App->model('DB::User')->find( { phone => '+61491570156' } ); + my $user = FixMyStreet::App->model('DB::User')->find( { phone => '+18165550100' } ); ok $user, "user created"; is $mech->uri->path, '/my', "redirected to the 'my' section of site"; $mech->logged_in_ok; @@ -76,13 +76,13 @@ subtest 'Log in using mobile, by password' => sub { $mech->get_ok('/auth'); $mech->submit_form_ok({ form_name => 'general_auth', - fields => { username => '+61491570156', password_sign_in => 'incorrect' }, + fields => { username => '+18165550100', password_sign_in => 'incorrect' }, button => 'sign_in_by_password', }, "sign in using wrong password"); $mech->content_contains('There was a problem'); $mech->submit_form_ok({ form_name => 'general_auth', - fields => { username => '+61491570156', password_sign_in => 'secret' }, + fields => { username => '+18165550100', password_sign_in => 'secret' }, button => 'sign_in_by_password', }, "sign in using password"); diff --git a/t/app/controller/report_inspect.t b/t/app/controller/report_inspect.t index 45bb4f8a7..f74c94c34 100644 --- a/t/app/controller/report_inspect.t +++ b/t/app/controller/report_inspect.t @@ -11,10 +11,18 @@ my $rp = FixMyStreet::DB->resultset("ResponsePriority")->create({ body => $oxon, name => 'High Priority', }); +my $rp2 = FixMyStreet::DB->resultset("ResponsePriority")->create({ + body => $oxon, + name => 'Low Priority', +}); FixMyStreet::DB->resultset("ContactResponsePriority")->create({ contact => $contact, response_priority => $rp, }); +FixMyStreet::DB->resultset("ContactResponsePriority")->create({ + contact => $contact3, + response_priority => $rp2, +}); my $wodc = $mech->create_body_ok(2420, 'West Oxfordshire District Council'); $mech->create_contact_ok( body_id => $wodc->id, category => 'Horses', email => 'horses@example.net' ); @@ -254,7 +262,7 @@ FixMyStreet::override_config { $mech->submit_form_ok({ button => 'save', with_fields => { - $test->{priority} ? (priority => 1) : (), + $test->{priority} ? (priority => $rp->id) : (), $test->{category} ? (category => 'Cows') : (), $test->{detailed} ? (detailed_information => 'Highland ones') : (), } @@ -262,6 +270,68 @@ FixMyStreet::override_config { }; } + subtest "check priority not set for category with no priorities" => sub { + $report->discard_changes; + $report->update({ category => 'Cows', response_priority_id => undef }); + $report->discard_changes; + is $report->response_priority, undef, 'response priority not set'; + $user->user_body_permissions->delete; + $user->user_body_permissions->create({ body => $oxon, permission_type => 'report_edit_category' }); + $user->user_body_permissions->create({ body => $oxon, permission_type => 'report_edit_priority' }); + $mech->get_ok("/report/$report_id"); + $mech->submit_form_ok({ + button => 'save', + with_fields => { + priority => $rp->id, + category => 'Sheep', + } + }); + + $report->discard_changes; + is $report->response_priority, undef, 'response priority not set'; + }; + + subtest "check can set priority for category when changing from category with no priorities" => sub { + $report->discard_changes; + $report->update({ category => 'Sheep', response_priority_id => undef }); + $report->discard_changes; + is $report->response_priority, undef, 'response priority not set'; + $user->user_body_permissions->delete; + $user->user_body_permissions->create({ body => $oxon, permission_type => 'report_edit_category' }); + $user->user_body_permissions->create({ body => $oxon, permission_type => 'report_edit_priority' }); + $mech->get_ok("/report/$report_id"); + $mech->submit_form_ok({ + button => 'save', + with_fields => { + priority => $rp->id, + category => 'Cows', + } + }); + + $report->discard_changes; + is $report->response_priority->id, $rp->id, 'response priority set'; + }; + + subtest "check can't set priority that isn't for a category" => sub { + $report->discard_changes; + $report->update({ category => 'Cows', response_priority_id => $rp->id }); + $report->discard_changes; + is $report->response_priority->id, $rp->id, 'response priority set'; + $user->user_body_permissions->delete; + $user->user_body_permissions->create({ body => $oxon, permission_type => 'report_edit_category' }); + $user->user_body_permissions->create({ body => $oxon, permission_type => 'report_edit_priority' }); + $mech->get_ok("/report/$report_id"); + $mech->submit_form_ok({ + button => 'save', + with_fields => { + priority => $rp2->id, + } + }); + + $report->discard_changes; + is $report->response_priority, undef, 'response priority set'; + }; + subtest "check nearest address display" => sub { $mech->get_ok("/report/$report_id"); $mech->content_lacks('Nearest calculated address', 'No address displayed'); @@ -408,6 +478,61 @@ FixMyStreet::override_config { }; FixMyStreet::override_config { + MAPIT_URL => 'http://mapit.uk/', + ALLOWED_COBRANDS => 'fixmystreet', +}, sub { + subtest "test category not updated if fail to include public update" => sub { + $mech->get_ok("/report/$report_id"); + $mech->submit_form(button => 'save', with_fields => { category => 'Badgers' }); + + $report->discard_changes; + is $report->category, "Cows", "Report in correct category"; + $mech->content_contains('Badgers" selected', 'Changed category still selected'); + }; + + subtest "test invalid form maintains Category and priority" => sub { + $mech->get_ok("/report/$report_id"); + my $expected_fields = { + state => 'action scheduled', + category => 'Cows', + public_update => '', + priority => $rp->id, + include_update => '1', + detailed_information => 'XXX172XXXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', + defect_type => '', + traffic_information => '' + }; + my $values = $mech->visible_form_values('report_inspect_form'); + is_deeply $values, $expected_fields, 'correct form fields present'; + + $mech->submit_form(button => 'save', with_fields => { category => 'Badgers', priority => $rp2->id }); + + $expected_fields->{category} = 'Badgers'; + $expected_fields->{priority} = $rp2->id; + + my $new_values = $mech->visible_form_values('report_inspect_form'); + is_deeply $new_values, $expected_fields, 'correct form fields present'; + }; + + subtest "test changing category and leaving an update only creates one comment" => sub { + $report->comments->delete; + $mech->get_ok("/report/$report_id"); + $mech->submit_form( + button => 'save', + with_fields => { + category => 'Badgers', + include_update => 1, + public_update => 'This is a public update', + }); + + $report->discard_changes; + is $report->category, "Badgers", "Report in correct category"; + is $report->comments->count, 1, "Only leaves one update"; + like $report->comments->first->text, qr/Category changed.*Badgers/, 'update text included category change'; + }; +}; + +FixMyStreet::override_config { ALLOWED_COBRANDS => [ 'oxfordshire', 'fixmystreet' ], BASE_URL => 'http://fixmystreet.site', }, sub { diff --git a/t/app/controller/reports.t b/t/app/controller/reports.t index f3958a0a5..7773223dd 100644 --- a/t/app/controller/reports.t +++ b/t/app/controller/reports.t @@ -114,6 +114,18 @@ FixMyStreet::override_config { MAPIT_URL => 'http://mapit.uk/', }, sub { $mech->submit_form_ok( { with_fields => { body => $body_edin_id } }, 'Submitted dropdown okay' ); + is $mech->uri->path, '/reports/City+of+Edinburgh+Council'; + + subtest "test ward pages" => sub { + $mech->get_ok('/reports/Birmingham/Bad-Ward'); + is $mech->uri->path, '/reports/Birmingham+City+Council'; + $mech->get_ok('/reports/Birmingham/Aston'); + is $mech->uri->path, '/reports/Birmingham+City+Council/Aston'; + $mech->get_ok('/reports/Birmingham/Aston|Bournville'); + is $mech->uri->path, '/reports/Birmingham+City+Council/Aston%7CBournville'; + $mech->content_contains('Aston, Bournville'); + }; + $mech->get_ok('/reports/Westminster'); }; diff --git a/templates/email/fixamingata/submit.html b/templates/email/fixamingata/submit.html index dfc56589a..65a692058 100644 --- a/templates/email/fixamingata/submit.html +++ b/templates/email/fixamingata/submit.html @@ -34,7 +34,6 @@ tror medborgaren behöver er uppmärksamhet.</p> [%~ END ~%] </td> </tr> - [% END %] [%~ IF phone %] <tr> <th style="[% contact_th_style %]">Telefon</th> diff --git a/templates/web/base/admin/areastats/area.html b/templates/web/base/admin/areastats/area.html index 1b88b5885..a7330692d 100644 --- a/templates/web/base/admin/areastats/area.html +++ b/templates/web/base/admin/areastats/area.html @@ -47,7 +47,7 @@ [% END %] </table> -[% IF average > 0 %] +[% IF average >= 0 %] <p>[% tprintf(loc('In the last month – average time between issue being opened and set to another status was %s days'), average) %]</p> [% ELSE %] <p>[% loc('In the last month no problems changed state') %]</p> diff --git a/templates/web/base/around/lookup_by_ref.html b/templates/web/base/around/lookup_by_ref.html index aded05638..5c08a7ceb 100644 --- a/templates/web/base/around/lookup_by_ref.html +++ b/templates/web/base/around/lookup_by_ref.html @@ -1,7 +1,7 @@ [% pre_container_extra = INCLUDE 'around/postcode_form.html', pc = ref %] [% INCLUDE 'header.html', title = loc('Reporting a problem'), bodyclass = 'frontpage fullwidthpage' %] -<div class="tablewrapper"> +[% IF matching_reports %] <p>[% loc('We found more than one match for that problem reference:') %]</p> <ul class="pc_alternatives"> [% FOREACH report IN matching_reports %] @@ -13,6 +13,8 @@ </li> [% END %] </ul> -</div> + [% ELSE %] + <p>[% loc('Searching found no reports.') %]</p> +[% END %] [% INCLUDE 'footer.html' %] diff --git a/templates/web/base/maps/openlayers.html b/templates/web/base/maps/openlayers.html index 8f8d527e2..568a87e7c 100644 --- a/templates/web/base/maps/openlayers.html +++ b/templates/web/base/maps/openlayers.html @@ -36,6 +36,4 @@ [% IF map.copyright %] <div class="olControlAttribution" style="position: absolute;">[% map.copyright %]</div> [% END %] - <div id="loading-indicator" class="hidden" aria-hidden="true"> - <img src="/i/loading.svg" alt="Loading..." /> - </div> + <img id="loading-indicator" class="hidden" aria-hidden="true" src="/i/loading.svg" alt="Loading..."> diff --git a/templates/web/base/report/_inspect.html b/templates/web/base/report/_inspect.html index 973db649e..e4e3ac9e6 100644 --- a/templates/web/base/report/_inspect.html +++ b/templates/web/base/report/_inspect.html @@ -6,7 +6,7 @@ [% INCLUDE 'errors.html' %] - <form id="report_inspect_form" method="post" action="[% c.uri_for( '/report', problem.id ) %]" class="validate"> + <form name="report_inspect_form" id="report_inspect_form" method="post" action="[% c.uri_for( '/report', problem.id ) %]" class="validate"> <input type="hidden" name="js" value=""> <div class="inspect-section"> diff --git a/templates/web/base/reports/body.html b/templates/web/base/reports/body.html index b6e6df73b..7931ae691 100755 --- a/templates/web/base/reports/body.html +++ b/templates/web/base/reports/body.html @@ -42,7 +42,12 @@ [% ward.name %] </h1> <a href="[% body_url %]">[% body.name %]</a> - [% ELSE %] + [% ELSIF wards %] + <h1 id="reports_heading"> + [% FOREACH w IN wards %][% w.name %][% IF NOT loop.last %], [% END %][% END %] + </h1> + <a href="[% body_url %]">[% body.name %]</a> + [% ELSE %] <h1 id="reports_heading"> [% body.name %] </h1> diff --git a/templates/web/oxfordshire/_email_sent_extra.html b/templates/web/oxfordshire/_email_sent_extra.html index 5fdcd3bfd..f01c2d5fb 100644 --- a/templates/web/oxfordshire/_email_sent_extra.html +++ b/templates/web/oxfordshire/_email_sent_extra.html @@ -1 +1,2 @@ -[% INCLUDE '_response_time.html' problem=report %] +[% DEFAULT problem = report %] +[% IF problem %][% INCLUDE '_response_time.html' %][% END %] diff --git a/web/cobrands/fixmystreet/fixmystreet.js b/web/cobrands/fixmystreet/fixmystreet.js index 3bf78ee31..cc156569f 100644 --- a/web/cobrands/fixmystreet/fixmystreet.js +++ b/web/cobrands/fixmystreet/fixmystreet.js @@ -659,7 +659,7 @@ $.extend(fixmystreet.set_up, { } $('#key-tools li:empty').remove(); $('#report-updates-data').insertAfter($('#map_box')); - if (fixmystreet.page === 'report' || fixmystreet.page === 'reports') { + if (fixmystreet.page !== 'around') { $('#sub_map_links').append('<a href="#" id="toggle-fullscreen" class="expand" data-expand-text="'+ translation_strings.expand_map +'" data-compress-text="'+ translation_strings.collapse_map +'" >'+ translation_strings.expand_map +'</span>'); } } diff --git a/web/cobrands/sass/_base.scss b/web/cobrands/sass/_base.scss index 9d6052c45..b13dc636a 100644 --- a/web/cobrands/sass/_base.scss +++ b/web/cobrands/sass/_base.scss @@ -1626,24 +1626,6 @@ html.js #map .noscript { } } -// Loading indicator - -#loading-indicator { - position: absolute; - width: 100%; - height: 100%; - background-color: #000; - opacity: 0.4; - text-align: center; - - img { - position: absolute; - left: 50%; - top: 50%; - transform: translate(-50%, -50%); - } -} - .big-green-banner { position: relative; top: -1.75em; @@ -1786,6 +1768,23 @@ a:hover.rap-notes-trigger { } } +#loading-indicator { + height: 32px; + width: 32px; + position: relative; + background-color: #333; + border-radius: 0.25em; + padding: 0.25em; + // Offset from top same as fms_pan_zoom, from left so as not + // to appear on top of zoom buttons (0.5em, 36px, 0.5em) + top: 0.5em; + left: 3.25em; + .map-reporting & { + // Same as fms_pan_zoom above, leaving space for the top bar when reporting + top: 2.75em; + } +} + /* Reporting a problem bits */ label .muted { diff --git a/web/cobrands/sass/_layout.scss b/web/cobrands/sass/_layout.scss index a0c27863e..5a78ff4d5 100644 --- a/web/cobrands/sass/_layout.scss +++ b/web/cobrands/sass/_layout.scss @@ -720,6 +720,14 @@ body.authpage { margin-bottom: 0; } +#loading-indicator { + height: 64px; + width: 64px; + background-color: rgba(0, 0, 0, 0.7); + // Reset the base left, as zoom buttons now elsewhere + left: 0.5em; +} + .big-green-banner { top: auto; margin: (-1em/1.375) (-1em/1.375) 0 (-1em/1.375); |