aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md1
-rw-r--r--cpanfile2
-rw-r--r--cpanfile.snapshot6
-rw-r--r--perllib/FixMyStreet/App/Controller/Admin.pm38
-rw-r--r--perllib/FixMyStreet/App/View/Web.pm18
-rw-r--r--perllib/FixMyStreet/DB/Result/User.pm15
-rw-r--r--t/app/controller/index.t17
-rw-r--r--templates/web/base/admin/user-form.html17
-rw-r--r--templates/web/base/around/postcode_form.html3
-rw-r--r--templates/web/base/footer.html2
-rw-r--r--templates/web/base/report/update.html2
-rw-r--r--templates/web/oxfordshire/footer.html2
-rw-r--r--templates/web/oxfordshire/header.html2
-rw-r--r--web/js/fixmystreet-admin.js3
14 files changed, 119 insertions, 9 deletions
diff --git a/README.md b/README.md
index e888c8121..9cab36688 100644
--- a/README.md
+++ b/README.md
@@ -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.
diff --git a/cpanfile b/cpanfile
index 7916a71eb..c96e05f36 100644
--- a/cpanfile
+++ b/cpanfile
@@ -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