diff options
-rw-r--r-- | README.md | 1 | ||||
-rw-r--r-- | cpanfile | 2 | ||||
-rw-r--r-- | cpanfile.snapshot | 6 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Admin.pm | 38 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/View/Web.pm | 18 | ||||
-rw-r--r-- | perllib/FixMyStreet/DB/Result/User.pm | 15 | ||||
-rw-r--r-- | t/app/controller/index.t | 17 | ||||
-rw-r--r-- | templates/web/base/admin/user-form.html | 17 | ||||
-rw-r--r-- | templates/web/base/around/postcode_form.html | 3 | ||||
-rw-r--r-- | templates/web/base/footer.html | 2 | ||||
-rw-r--r-- | templates/web/base/report/update.html | 2 | ||||
-rw-r--r-- | templates/web/oxfordshire/footer.html | 2 | ||||
-rw-r--r-- | templates/web/oxfordshire/header.html | 2 | ||||
-rw-r--r-- | web/js/fixmystreet-admin.js | 3 |
14 files changed, 119 insertions, 9 deletions
@@ -75,6 +75,7 @@ web-based cross-browser testing tools for this project. - Show any waiting reports on admin index page. #1382 - Allow user's phone number to be edited, and a report's category. #400 - Resend report if changing category changes body. #1560. + - Leave a public update if an admin changes a report's category. #1544 - New user system: - /admin requires a user with the `is_superuser` flag. #1463 - `createsuperuser` command for creating superusers. @@ -73,7 +73,7 @@ requires 'Moose'; requires 'MooX::Types::MooseLike'; requires 'namespace::autoclean'; requires 'Net::DNS::Resolver'; -requires 'Net::Domain::TLD', '1.74'; +requires 'Net::Domain::TLD', '1.75'; requires 'Net::Facebook::Oauth2'; requires 'Net::OAuth'; requires 'Net::SMTP::SSL', '1.03'; diff --git a/cpanfile.snapshot b/cpanfile.snapshot index 1b11c37a2..2c565f8cd 100644 --- a/cpanfile.snapshot +++ b/cpanfile.snapshot @@ -4302,10 +4302,10 @@ DISTRIBUTIONS IO::Socket 0 MIME::Base64 2.11 Test::More 0.18 - Net-Domain-TLD-1.74 - pathname: A/AL/ALEXP/Net-Domain-TLD-1.74.tar.gz + Net-Domain-TLD-1.75 + pathname: A/AL/ALEXP/Net-Domain-TLD-1.75.tar.gz provides: - Net::Domain::TLD 1.74 + Net::Domain::TLD 1.75 requirements: Carp 0 ExtUtils::MakeMaker 0 diff --git a/perllib/FixMyStreet/App/Controller/Admin.pm b/perllib/FixMyStreet/App/Controller/Admin.pm index c4bd5c293..e91597bb0 100644 --- a/perllib/FixMyStreet/App/Controller/Admin.pm +++ b/perllib/FixMyStreet/App/Controller/Admin.pm @@ -841,6 +841,7 @@ sub report_edit_category : Private { my ($self, $c, $problem) = @_; if ((my $category = $c->get_param('category')) ne $problem->category) { + my $category_old = $problem->category; $problem->category($category); my @contacts = grep { $_->category eq $problem->category } @{$c->stash->{contacts}}; my @new_body_ids = map { $_->body_id } @contacts; @@ -849,6 +850,16 @@ sub report_edit_category : Private { $problem->whensent(undef); } $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, + }); } } @@ -1330,6 +1341,17 @@ sub user_edit : Path('user_edit') : Args(1) { } $c->stash->{field_errors} = {}; + + # Update the categories this user operates in + if ( $user->from_body ) { + $c->stash->{body} = $user->from_body; + $c->forward('fetch_contacts'); + my @live_contacts = $c->stash->{live_contacts}->all; + my @live_contact_ids = map { $_->id } @live_contacts; + my @new_contact_ids = grep { $c->get_param("contacts[$_]") } @live_contact_ids; + $user->set_extra_metadata('categories', \@new_contact_ids); + } + unless ($user->email) { $c->stash->{field_errors}->{email} = _('Please enter a valid email'); } @@ -1354,6 +1376,22 @@ sub user_edit : Path('user_edit') : Args(1) { '<p><em>' . _('Updated!') . '</em></p>'; } + if ( $user->from_body ) { + unless ( $c->stash->{body} && $user->from_body->id eq $c->stash->{body}->id ) { + $c->stash->{body} = $user->from_body; + $c->forward('fetch_contacts'); + } + my @contacts = @{$user->get_extra_metadata('categories') || []}; + my %active_contacts = map { $_ => 1 } @contacts; + my @live_contacts = $c->stash->{live_contacts}->all; + my @all_contacts = map { { + id => $_->id, + category => $_->category, + active => $active_contacts{$_->id}, + } } @live_contacts; + $c->stash->{contacts} = \@all_contacts; + } + return 1; } diff --git a/perllib/FixMyStreet/App/View/Web.pm b/perllib/FixMyStreet/App/View/Web.pm index ae06181c8..f0bcad0be 100644 --- a/perllib/FixMyStreet/App/View/Web.pm +++ b/perllib/FixMyStreet/App/View/Web.pm @@ -22,6 +22,7 @@ __PACKAGE__->config( FILTERS => { add_links => \&add_links, escape_js => \&escape_js, + markup => [ \&markup_factory, 1 ], }, COMPILE_EXT => '.ttc', STAT_TTL => FixMyStreet->config('STAGING_SITE') ? 1 : 86400, @@ -98,6 +99,23 @@ sub _space_slash { return $t; } +=head2 markup_factory + +This returns a function that will allow updates to have markdown-style italics. +Pass in the user that wrote the text, so we know whether it can be privileged. + +=cut + +sub markup_factory { + my ($c, $user) = @_; + return sub { + my $text = shift; + return $text unless $user && ($user->from_body || $user->is_superuser); + $text =~ s{\*(\S.*?\S)\*}{<i>$1</i>}; + $text; + } +} + =head2 escape_js Used to escape strings that are going to be put inside JavaScript. diff --git a/perllib/FixMyStreet/DB/Result/User.pm b/perllib/FixMyStreet/DB/Result/User.pm index 7ec49b074..028394795 100644 --- a/perllib/FixMyStreet/DB/Result/User.pm +++ b/perllib/FixMyStreet/DB/Result/User.pm @@ -391,4 +391,19 @@ sub update_reputation { $self->update; } +has categories => ( + is => 'ro', + lazy => 1, + default => sub { + my $self = shift; + return [] unless $self->get_extra_metadata('categories'); + my @categories = $self->result_source->schema->resultset("Contact")->search({ + id => $self->get_extra_metadata('categories'), + }, { + order_by => 'category', + })->get_column('category')->all; + return \@categories; + }, +); + 1; diff --git a/t/app/controller/index.t b/t/app/controller/index.t index 346ccb2e1..6752d4d7e 100644 --- a/t/app/controller/index.t +++ b/t/app/controller/index.t @@ -80,7 +80,24 @@ ok $mech->get('/report/' . $edinburgh_problems[2]->id); is $mech->res->code, 403, 'page forbidden'; is $problem_rs->count, $num+5; +my $oxon = $mech->create_body_ok(2237, 'Oxfordshire County Council', id => 2237); +subtest "prefilters /around if user has categories" => sub { + my $user = $mech->log_in_ok('test@example.com'); + my $categories = [ + $mech->create_contact_ok( body_id => $oxon->id, category => 'Cows', email => 'cows@example.net' )->id, + $mech->create_contact_ok( body_id => $oxon->id, category => 'Potholes', email => 'potholes@example.net' )->id, + ]; + $user->from_body($oxon); + $user->set_extra_metadata('categories', $categories); + $user->update; + + $mech->get_ok('/'); + # NB can't use visible_form_values because categories field is hidden + $mech->content_contains("Cows,Potholes"); +}; + END { $mech->delete_problems_for_body( 2651 ); + $mech->delete_body($oxon); done_testing(); } diff --git a/templates/web/base/admin/user-form.html b/templates/web/base/admin/user-form.html index 388434e80..cfd85b465 100644 --- a/templates/web/base/admin/user-form.html +++ b/templates/web/base/admin/user-form.html @@ -71,6 +71,19 @@ </li> [% END %] + [% IF contacts AND c.cobrand.moniker != 'zurich'%] + <li class="js-user-categories"> + <div class="admin-hint"> + <p> + [% loc( + "Authorised staff users can be associated with the categories in which they operate.") + %] + </p> + </div> + [% INCLUDE 'admin/category-checkboxes.html' %] + </li> + [% END %] + [% IF c.cobrand.moniker != 'zurich' %] <li> @@ -142,6 +155,10 @@ <li> [% group.key %] <ul class="no-bullets"> + <li> + (<a href="#" data-select-all>[% loc('all') %]</a> / + <a href="#" data-select-none>[% loc('none') %]</a>) + </li> [% FOREACH permission IN group.value %] <li> <label class="inline"> diff --git a/templates/web/base/around/postcode_form.html b/templates/web/base/around/postcode_form.html index 9c0bc5942..135a70294 100644 --- a/templates/web/base/around/postcode_form.html +++ b/templates/web/base/around/postcode_form.html @@ -17,6 +17,9 @@ <input type="hidden" name="partial" value="[% partial_token.token %]"> [% END %] + [% IF c.user_exists AND c.user.categories.size %] + <input type="hidden" name="filter_category" value="[% c.user.categories.join(",") | html %]"> + [% END %] </form> </div> </div> diff --git a/templates/web/base/footer.html b/templates/web/base/footer.html index 0356840da..5fd74b3a1 100644 --- a/templates/web/base/footer.html +++ b/templates/web/base/footer.html @@ -25,7 +25,7 @@ %]span[% ELSE %]a href="[% base %]/my"[% END %]>[% c.user_exists ? loc("Your account") : loc("Sign in") %]</[% c.req.uri.path == '/my' ? 'span' : 'a' %]></li>[% %]<li><[% IF c.req.uri.path == '/reports' - %]span[% ELSE %]a href="[% base %]/reports"[% END + %]span[% ELSE %]a href="[% base %]/reports[% IF c.user_exists AND c.user.categories.size %]?filter_category=[% c.user.categories.join(",") | uri | html %][% END %]"[% END %]>[% loc("All reports") %]</[% c.req.uri.path == '/reports' ? 'span' : 'a' %]></li>[% %]<li><[% IF c.req.uri.path == '/alert' %]span[% ELSE %]a href="[% base %]/alert[% pc ? '/list?pc=' : '' %][% pc | uri %]"[% END diff --git a/templates/web/base/report/update.html b/templates/web/base/report/update.html index 7c2c39eb2..d423a193d 100644 --- a/templates/web/base/report/update.html +++ b/templates/web/base/report/update.html @@ -31,7 +31,7 @@ [% INCLUDE 'report/photo.html' object=update %] <div class="item-list__update-text"> <div class="moderate-display"> - [% update.text | add_links | html_para %] + [% update.text | add_links | markup(update.user) | html_para %] </div> [% IF moderating %] <div class="moderate-edit"> diff --git a/templates/web/oxfordshire/footer.html b/templates/web/oxfordshire/footer.html index b59ded05d..89a9f89de 100644 --- a/templates/web/oxfordshire/footer.html +++ b/templates/web/oxfordshire/footer.html @@ -22,7 +22,7 @@ %][% IF c.user_exists AND c.user.has_body_permission_to('planned_reports') %]<li> <[% IF c.req.uri.path == '/my/planned' %]span[% ELSE %]a href="/my/planned"[% END %]>[% loc('Shortlist') %]</[% c.req.uri.path == '/my/planned' ? 'span' : 'a' %]></li>[% - %][% END %]<li><[% IF c.req.uri.path == '/reports' %]span[% ELSE %]a href="/reports"[% END + %][% END %]<li><[% IF c.req.uri.path == '/reports' %]span[% ELSE %]a href="/reports[% IF c.user_exists AND c.user.categories.size %]?filter_category=[% c.user.categories.join(",") | uri | html %][% END %]"[% END %]>[% loc("All reports") %]</[% c.req.uri.path == '/reports' ? 'span' : 'a' %]></li>[% %]<li><[% IF c.req.uri.path == '/alert' %]span[% ELSE %]a href="/alert[% pc ? '/list?pc=' : '' %][% pc | uri %]"[% END %]>[% loc("Local alerts") %]</[% c.req.uri.path == '/alert' ? 'span' : 'a' %]></li>[% diff --git a/templates/web/oxfordshire/header.html b/templates/web/oxfordshire/header.html index 5b5532b67..042222e1d 100644 --- a/templates/web/oxfordshire/header.html +++ b/templates/web/oxfordshire/header.html @@ -49,7 +49,7 @@ </li> [% END %] <li> - <[% IF c.req.uri.path == '/reports/Oxfordshire' %]span[% ELSE %]a href="/reports/Oxfordshire"[% END + <[% IF c.req.uri.path == '/reports/Oxfordshire' %]span[% ELSE %]a href="/reports/Oxfordshire[% IF c.user_exists AND c.user.categories.size %]?filter_category=[% c.user.categories.join(",") | uri | html %][% END %]"[% END %]>[% loc("All reports") %]</[% c.req.uri.path == '/reports' ? 'span' : 'a' %]> </li> <li> diff --git a/web/js/fixmystreet-admin.js b/web/js/fixmystreet-admin.js index 0323b1742..884ad1c09 100644 --- a/web/js/fixmystreet-admin.js +++ b/web/js/fixmystreet-admin.js @@ -84,10 +84,11 @@ $(function(){ } }); - // On user edit page, hide the area select field if body changes + // On user edit page, hide the area/categories fields if body changes $("form#user_edit select#body").change(function() { var show_area = $(this).val() == $(this).find("[data-originally-selected]").val(); $("form#user_edit select#area_id").closest("li").toggle(show_area); + $("form#user_edit .js-user-categories").toggle(show_area); }); // On category edit page, hide the reputation input if inspection isn't required |