diff options
-rw-r--r-- | perllib/FixMyStreet/DB/Result/Problem.pm | 12 | ||||
-rw-r--r-- | perllib/FixMyStreet/DB/Result/User.pm | 15 | ||||
-rw-r--r-- | perllib/FixMyStreet/DB/ResultSet/UserPlannedReport.pm | 23 | ||||
-rw-r--r-- | t/app/model/user_planned_report.t | 18 | ||||
-rw-r--r-- | templates/web/base/report/_main.html | 7 | ||||
-rw-r--r-- | web/cobrands/fixmystreet/images/shortlist.png | bin | 0 -> 343 bytes | |||
-rw-r--r-- | web/cobrands/fixmystreet/images/shortlist.svg | 1 | ||||
-rw-r--r-- | web/cobrands/fixmystreet/images/shortlist@2.png | bin | 0 -> 619 bytes | |||
-rw-r--r-- | web/cobrands/sass/_base.scss | 28 |
9 files changed, 99 insertions, 5 deletions
diff --git a/perllib/FixMyStreet/DB/Result/Problem.pm b/perllib/FixMyStreet/DB/Result/Problem.pm index 27648ddad..855732f83 100644 --- a/perllib/FixMyStreet/DB/Result/Problem.pm +++ b/perllib/FixMyStreet/DB/Result/Problem.pm @@ -1020,4 +1020,16 @@ sub static_map { }; } +has shortlisted_user => ( + is => 'ro', + lazy => 1, + default => sub { + my $self = shift; + my $user = $self->result_source->schema->resultset('User')->search( + { 'user_planned_reports.report_id' => $self->id }, + { join => 'user_planned_reports' })->first; + return $user; + }, +); + 1; diff --git a/perllib/FixMyStreet/DB/Result/User.pm b/perllib/FixMyStreet/DB/Result/User.pm index 8d42d5926..7ec49b074 100644 --- a/perllib/FixMyStreet/DB/Result/User.pm +++ b/perllib/FixMyStreet/DB/Result/User.pm @@ -351,11 +351,18 @@ sub adopt { # Planned reports / shortlist -# Override the default auto-created function as we only want one live entry per user +# Override the default auto-created function as we only want one live entry so +# we need to delete it anywhere else and return an existing one if present. around add_to_planned_reports => sub { my ( $orig, $self ) = ( shift, shift ); my ( $report_col ) = @_; - my $existing = $self->user_planned_reports->search_rs({ report_id => $report_col->{id}, removed => undef })->first; + + $self->result_source->schema->resultset("UserPlannedReport") + ->active + ->for_report($report_col->id) + ->search_rs({ user_id => { '!=', $self->id } }) + ->remove(); + my $existing = $self->user_planned_reports->active->for_report($report_col->id)->first; return $existing if $existing; return $self->$orig(@_); }; @@ -363,9 +370,7 @@ around add_to_planned_reports => sub { # Override the default auto-created function as we don't want to ever delete anything around remove_from_planned_reports => sub { my ($orig, $self, $report) = @_; - $self->user_planned_reports - ->search_rs({ report_id => $report->id, removed => undef }) - ->update({ removed => \'current_timestamp' }); + $self->user_planned_reports->active->for_report($report->id)->remove(); }; sub active_planned_reports { diff --git a/perllib/FixMyStreet/DB/ResultSet/UserPlannedReport.pm b/perllib/FixMyStreet/DB/ResultSet/UserPlannedReport.pm new file mode 100644 index 000000000..7e16e2dd3 --- /dev/null +++ b/perllib/FixMyStreet/DB/ResultSet/UserPlannedReport.pm @@ -0,0 +1,23 @@ +package FixMyStreet::DB::ResultSet::UserPlannedReport; +use base 'DBIx::Class::ResultSet'; + +use strict; +use warnings; + +sub active { + my $rs = shift; + $rs->search({ removed => undef }); +} + +sub for_report { + my $rs = shift; + my $problem_id = shift; + $rs->search({ report_id => $problem_id }); +} + +sub remove { + my $rs = shift; + $rs->update({ removed => \'current_timestamp' }); +} + +1; diff --git a/t/app/model/user_planned_report.t b/t/app/model/user_planned_report.t index 6c0823044..95a76615e 100644 --- a/t/app/model/user_planned_report.t +++ b/t/app/model/user_planned_report.t @@ -11,6 +11,7 @@ my $mech = FixMyStreet::TestMech->new(); my @problems = $mech->create_problems_for_body(1, 2237, 'Title'); my $problem = $problems[0]; my $user = $problem->user; +my $user2 = $mech->create_user_ok('other@example.net'); is $user->active_planned_reports, 0; is $user->planned_reports, 0; @@ -19,6 +20,10 @@ $user->add_to_planned_reports($problem); is $user->active_planned_reports, 1; is $user->planned_reports, 1; +$user->add_to_planned_reports($problem); +is $user->active_planned_reports, 1; +is $user->planned_reports, 1; + $user->remove_from_planned_reports($problem); is $user->active_planned_reports, 0; is $user->planned_reports, 1; @@ -27,8 +32,21 @@ $user->add_to_planned_reports($problem); is $user->active_planned_reports, 1; is $user->planned_reports, 2; +$user2->add_to_planned_reports($problem); +is $user->active_planned_reports, 0; +is $user->planned_reports, 2; +is $user2->active_planned_reports, 1; +is $user2->planned_reports, 1; + +$user->add_to_planned_reports($problem); +is $user->active_planned_reports, 1; +is $user->planned_reports, 3; +is $user2->active_planned_reports, 0; +is $user2->planned_reports, 1; + done_testing(); END { $mech->delete_user($user); + $mech->delete_user($user2); } diff --git a/templates/web/base/report/_main.html b/templates/web/base/report/_main.html index 469ee5bc5..0a4056da7 100644 --- a/templates/web/base/report/_main.html +++ b/templates/web/base/report/_main.html @@ -147,5 +147,12 @@ </div> [% END %] + [% IF permissions.planned_reports AND problem.shortlisted_user AND NOT c.user.is_planned_report(problem) %] + <div class="moderate-display shortlisted-status"> + <h3>[% tprintf(loc('Shortlisted by %s'), problem.shortlisted_user.name) %]</h3> + <p>[% tprintf(loc('Adding this report to your shortlist will remove it from %s’s shortlist.'), problem.shortlisted_user.name) %]</p> + </div> + [% END %] + [% TRY %][% PROCESS 'report/_main_after.html' %][% CATCH file %][% END %] </div> diff --git a/web/cobrands/fixmystreet/images/shortlist.png b/web/cobrands/fixmystreet/images/shortlist.png Binary files differnew file mode 100644 index 000000000..d992f267f --- /dev/null +++ b/web/cobrands/fixmystreet/images/shortlist.png diff --git a/web/cobrands/fixmystreet/images/shortlist.svg b/web/cobrands/fixmystreet/images/shortlist.svg new file mode 100644 index 000000000..dc38d5893 --- /dev/null +++ b/web/cobrands/fixmystreet/images/shortlist.svg @@ -0,0 +1 @@ +<svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg"><title>Artboard</title><g fill="#000" fill-rule="evenodd"><path d="M17.4 8H32v4h-7.3l-.152-1.527L18 10l-.6-2zm3.1 12H32v4H21.03l-.53-4zm4.4-6H32v4h-9.7l2.7-3-.1-1z"/><path d="M4.914 26.995L11.56 23.5l6.646 3.495c.276-.185.545-.38.805-.587l-1.268-7.4 5.378-5.24c-.09-.322-.192-.637-.307-.946l-7.432-1.08-3.32-6.732c-.167-.007-.333-.01-.5-.01-.167 0-.333.003-.5.01l-3.32 6.732-7.433 1.08c-.115.31-.217.624-.307.945l5.378 5.242-1.27 7.398c.26.207.53.402.806.587z"/></g></svg>
\ No newline at end of file diff --git a/web/cobrands/fixmystreet/images/shortlist@2.png b/web/cobrands/fixmystreet/images/shortlist@2.png Binary files differnew file mode 100644 index 000000000..d786b33d3 --- /dev/null +++ b/web/cobrands/fixmystreet/images/shortlist@2.png diff --git a/web/cobrands/sass/_base.scss b/web/cobrands/sass/_base.scss index 612d8cf55..3c76a3990 100644 --- a/web/cobrands/sass/_base.scss +++ b/web/cobrands/sass/_base.scss @@ -1086,6 +1086,34 @@ input.final-submit { } } +.shortlisted-status { + margin-top: 1em; + padding: 1em 1em 1em 4em; // Icon is always displayed on left, even in RtL mode + border-radius: 0.25em; + border: 1px solid rgba(0, 0, 0, 0.1); + background: rgba(255, 255, 255, 0.5) url(/cobrands/fixmystreet/images/shortlist.png) 1em 50% no-repeat; + background-size: 2em 2em; + + @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { + background-image: url(/cobrands/fixmystreet/images/shortlist@2.png); + } + + @media all { + background-image: url(/cobrands/fixmystreet/images/shortlist.svg), none; + } + + h3 { + margin: 0; + font-size: 1em; + font-weight: bold; + } + + p { + margin: 0.5em 0 0 0; + font-size: 0.875em; + } +} + // map stuff #map_box { margin: 0 -1em 1em; |