aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--perllib/FixMyStreet/DB/Result/Problem.pm12
-rw-r--r--perllib/FixMyStreet/DB/Result/User.pm15
-rw-r--r--perllib/FixMyStreet/DB/ResultSet/UserPlannedReport.pm23
-rw-r--r--t/app/model/user_planned_report.t18
-rw-r--r--templates/web/base/report/_main.html7
-rw-r--r--web/cobrands/fixmystreet/images/shortlist.pngbin0 -> 343 bytes
-rw-r--r--web/cobrands/fixmystreet/images/shortlist.svg1
-rw-r--r--web/cobrands/fixmystreet/images/shortlist@2.pngbin0 -> 619 bytes
-rw-r--r--web/cobrands/sass/_base.scss28
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
new file mode 100644
index 000000000..d992f267f
--- /dev/null
+++ b/web/cobrands/fixmystreet/images/shortlist.png
Binary files differ
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
new file mode 100644
index 000000000..d786b33d3
--- /dev/null
+++ b/web/cobrands/fixmystreet/images/shortlist@2.png
Binary files differ
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;