Skip to content

Commit 783aad7

Browse files
committed
closes concerto#1516 moderator notification when submissions are pending
1 parent 7819229 commit 783aad7

20 files changed

+382
-167
lines changed

Gemfile-plugins

+7-14
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,7 @@
1-
2-
gem "concerto_weather", '>=0.6'
3-
4-
gem "concerto_remote_video", '>=1.2'
5-
6-
gem "concerto_simple_rss", '>=1.1'
7-
8-
gem "concerto_iframe", '>=0.1.0'
9-
10-
gem "concerto_calendar", '>=0.0.9'
11-
12-
gem "concerto_hardware", '>=0.8'
13-
14-
gem "concerto_frontend", '>=0.4.3'
1+
gem "concerto_calendar"
2+
gem "concerto_frontend"
3+
gem "concerto_hardware"
4+
gem "concerto_iframe"
5+
gem "concerto_remote_video"
6+
gem "concerto_simple_rss"
7+
gem "concerto_weather"

Gemfile.lock

+22-23
Original file line numberDiff line numberDiff line change
@@ -118,10 +118,9 @@ GEM
118118
faraday (0.9.2)
119119
multipart-post (>= 1.2, < 3)
120120
ffi (1.11.1)
121-
font-awesome-sass (5.9.0)
121+
font-awesome-sass (5.11.2)
122122
sassc (>= 1.11)
123-
foreman (0.85.0)
124-
thor (~> 0.19.1)
123+
foreman (0.86.0)
125124
girl_friday (0.11.2)
126125
connection_pool (~> 1.0)
127126
rubinius-actor
@@ -192,18 +191,18 @@ GEM
192191
logging (2.2.2)
193192
little-plugger (~> 1.1)
194193
multi_json (~> 1.10)
195-
loofah (2.2.3)
194+
loofah (2.3.0)
196195
crass (~> 1.0.2)
197196
nokogiri (>= 1.5.9)
198197
mail (2.7.1)
199198
mini_mime (>= 0.1.1)
200199
memoist (0.16.0)
201-
mime-types (3.2.2)
200+
mime-types (3.3)
202201
mime-types-data (~> 3.2015)
203-
mime-types-data (3.2019.0331)
202+
mime-types-data (3.2019.1009)
204203
mini_mime (1.0.2)
205204
mini_portile2 (2.4.0)
206-
minitest (5.11.3)
205+
minitest (5.12.2)
207206
multi_json (1.13.1)
208207
multipart-post (2.1.1)
209208
mysql2 (0.5.2)
@@ -218,10 +217,10 @@ GEM
218217
open_uri_redirections (0.2.1)
219218
orm_adapter (0.5.0)
220219
os (0.9.6)
221-
parser (2.6.4.0)
220+
parser (2.6.5.0)
222221
ast (~> 2.4.0)
223222
pg (1.1.4)
224-
public_activity (1.6.3)
223+
public_activity (1.6.4)
225224
actionpack (>= 3.0.0)
226225
activerecord (>= 3.0)
227226
i18n (>= 0.5.0)
@@ -248,14 +247,14 @@ GEM
248247
activesupport (>= 4.2.0, < 5.0)
249248
nokogiri (~> 1.6)
250249
rails-deprecated_sanitizer (>= 1.0.1)
251-
rails-html-sanitizer (1.2.0)
252-
loofah (~> 2.2, >= 2.2.2)
250+
rails-html-sanitizer (1.3.0)
251+
loofah (~> 2.3)
253252
railties (4.2.11.1)
254253
actionpack (= 4.2.11.1)
255254
activesupport (= 4.2.11.1)
256255
rake (>= 0.8.7)
257256
thor (>= 0.18.1, < 2.0)
258-
rake (12.3.3)
257+
rake (13.0.0)
259258
rb-fsevent (0.10.3)
260259
rb-inotify (0.10.0)
261260
ffi (~> 1.0)
@@ -288,17 +287,17 @@ GEM
288287
sprockets (>= 2.8, < 4.0)
289288
sprockets-rails (>= 2.0, < 4.0)
290289
tilt (>= 1.1, < 3)
291-
sassc (2.2.0)
290+
sassc (2.2.1)
292291
ffi (~> 1.9)
293292
sawyer (0.6.0)
294293
addressable (~> 2.3.5)
295294
faraday (~> 0.8, < 0.10)
296-
signet (0.11.0)
295+
signet (0.12.0)
297296
addressable (~> 2.3)
298297
faraday (~> 0.9)
299298
jwt (>= 1.5, < 3.0)
300299
multi_json (~> 1.10)
301-
simplecov (0.17.0)
300+
simplecov (0.17.1)
302301
docile (~> 1.1)
303302
json (>= 1.8, < 3)
304303
simplecov-html (~> 0.10.0)
@@ -318,7 +317,7 @@ GEM
318317
tins (~> 1.0)
319318
terminal-table (1.8.0)
320319
unicode-display_width (~> 1.1, >= 1.1.1)
321-
thor (0.19.4)
320+
thor (0.20.3)
322321
thread (0.2.2)
323322
thread_safe (0.3.6)
324323
tilt (1.4.1)
@@ -360,14 +359,14 @@ DEPENDENCIES
360359
cancancan
361360
clockwork
362361
coffee-rails
363-
concerto_calendar (>= 0.0.9)
362+
concerto_calendar
364363
concerto_docsplit
365-
concerto_frontend (>= 0.4.3)
366-
concerto_hardware (>= 0.8)
367-
concerto_iframe (>= 0.1.0)
368-
concerto_remote_video (>= 1.2)
369-
concerto_simple_rss (>= 1.1)
370-
concerto_weather (>= 0.6)
364+
concerto_frontend
365+
concerto_hardware
366+
concerto_iframe
367+
concerto_remote_video
368+
concerto_simple_rss
369+
concerto_weather
371370
delayed_job_active_record
372371
devise!
373372
execjs (~> 2.2.2)

app/assets/stylesheets/application/views/users.scss

+19
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,23 @@
3838

3939
.orange {
4040
color: lighten($orange, 10%);
41+
}
42+
43+
.users-index {
44+
i.concertocon-user-admin, i.concertocon-user-leader {
45+
font-size: inherit;
46+
}
47+
48+
ul.groups-list {
49+
margin-left: 0;
50+
51+
li {
52+
float: left;
53+
padding-right: 2em;
54+
}
55+
56+
li:first-child {
57+
list-style-type: none;
58+
}
59+
}
4160
}

app/mailers/moderator_mailer.rb

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
class ModeratorMailer < ActionMailer::Base
2+
def items_pending(emails)
3+
if emails.present?
4+
mail to: emails, subject: t('.concerto_submission_pending_approval'), from: ConcertoConfig[:mailer_from] || 'concerto@example.com'
5+
end
6+
end
7+
end

app/models/group.rb

+4
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ def made_request?(user)
6666
all_users.include?(user)
6767
end
6868

69+
def moderators
70+
memberships.map { |m| m if m.is_moderator? }
71+
end
72+
6973
# Test if a user can be demoted to regular member or removed from a group
7074
def can_resign_leadership?(membership)
7175
return self.leaders.count > 1 || !membership.is_leader?

app/models/membership.rb

+4
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,10 @@ def is_leader?
128128
level == Membership::LEVELS[:leader]
129129
end
130130

131+
def is_moderator?
132+
is_leader? || (is_approved? && (perms[:feed] == :all || perms[:feed] == :submissions))
133+
end
134+
131135
# action can be {"approve, deny, promote, demote"}
132136
def update_membership_level(action)
133137
case action

app/models/submission.rb

+18-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ class Submission < ActiveRecord::Base
1818
scope :approved, -> { where moderation_flag: true }
1919
scope :denied, -> { where moderation_flag: false }
2020
scope :pending, -> { where "moderation_flag IS NULL" }
21+
scope :unsent, -> { where "pending_notification_sent IS NULL" }
2122

2223
# Scoping shortcuts for active/expired/future
2324
def self.active
@@ -66,7 +67,7 @@ def is_pending?
6667
end
6768

6869
# Cascade moderation to children submissions as well.
69-
# Child content submitted to the same feed will recieve the same moderation
70+
# Child content submitted to the same feed will receive the same moderation
7071
# as a parent content.
7172
def update_child_moderation
7273
if self.changed.include?('moderation_flag') and self.content.has_children?
@@ -94,4 +95,20 @@ def self.deny_old_expired
9495
end
9596
end
9697

98+
# if there are any pending submissions, send a notice to the unique list of moderators
99+
def self.send_moderation_request_notifications
100+
items = Submission.pending.unsent
101+
emails = items.map{|s| s.feed.group.moderators }.flatten.compact.map{|m| m.user.email if m.receive_emails && m.user.receive_moderation_notifications }.compact.sort.uniq
102+
103+
if items.present? && emails.present?
104+
Rails.logger.info "moderation request email sent to #{emails.join(', ')}"
105+
ModeratorMailer.items_pending(emails).deliver_now
106+
107+
# indicate that we sent a notification so we dont repeat emails for the same content
108+
items.each do |s|
109+
s.update_attributes(pending_notification_sent: DateTime.now)
110+
end
111+
end
112+
end
113+
97114
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
5+
<title>
6+
<%= t '.concerto_submission_pending_approval' %>
7+
</title>
8+
<style type="text/css">
9+
10+
body {
11+
margin: 0;
12+
padding: 0;
13+
font-family: 'Myriad Pro', Helvetica, Arial, sans-serif;
14+
height: 100% !important;
15+
width: 100% !important;
16+
17+
}
18+
19+
img {
20+
border: 0;
21+
width: 300px;;
22+
height: auto;
23+
line-height: 100%;
24+
outline: none;
25+
text-decoration: none;
26+
margin: auto;
27+
display: block;
28+
}
29+
30+
#messageblock {
31+
width: 600px;
32+
padding: 12px;
33+
background-color: white;
34+
-webkit-box-shadow: 0 3px 2px #ababab;
35+
-moz-box-shadow: 0 3px 2px #ababab;
36+
box-shadow: 0 3px 2px #ababab;
37+
display: block;
38+
margin: auto;
39+
-webkit-border-radius: 8px 8px 0px 0px;
40+
-moz-border-radius: 8px 8px 0px 0px;
41+
border-radius: 8px 8px 0px 0px;
42+
}
43+
44+
#message {
45+
text-align: left;
46+
}
47+
</style>
48+
</head>
49+
<body>
50+
<div id="messageblock">
51+
<%= image_tag '/images/full_logo.png', id: 'logo' %>
52+
<div id="message">
53+
<%= link_to t('.a_submission_is_pending_moderation'), moderate_feeds_url %>
54+
</div>
55+
</div>
56+
</body>
57+
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<%= t '.a_submission_is_pending_moderation' %>
2+
3+
<%= moderate_feeds_url %>

app/views/users/index.html.erb

+25-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<section class="viewblock">
1+
<section class="viewblock users-index">
22
<header class="viewblock-header">
33
<div class="viewblock-header_right">
44
<div class="button-padding">
@@ -28,9 +28,31 @@
2828
<% else %>
2929
<%= user.name %>
3030
<% end %>
31+
32+
<% if user.is_admin %><i class="concertocon-user-admin tooltip-basic" data-tooltip-text="<%= t('.system_admin') %>"></i><% end %>
33+
</td>
34+
<td>
35+
<%= user.email %>
36+
<% if user.receive_moderation_notifications %>
37+
<i class='fas fa-envelope muted tooltip-basic' data-tooltip-text="<%= User.human_attribute_name(:receive_moderation_notifications) %>"></i>
38+
<% end %>
39+
</td>
40+
<td>
41+
<%#= user.groups.map(&:name).join(",") %>
42+
<ul class="groups-list">
43+
<% user.memberships.sort{|a,b| a.group.name <=> b.group.name}.each do |m| %>
44+
<% next if m.is_denied? %>
45+
<li class="<%= m.is_denied? ? 'is_denied' : (m.is_pending? ? 'muted' : '') %>">
46+
<%= m.group.name %>
47+
<% if m.is_leader? %><i class="concertocon-user-leader muted tooltip-basic" data-tooltip-text="<%= t('.leader') %>"></i><% end %>
48+
<% if m.is_pending? %><i class="fas fa-question-circle tooltip-basic" data-tooltip-text="<%= t('.pending') %>"></i><% end %>
49+
<% if m.is_denied? %><i class="fas fa-thumbs-down tooltip-basic" data-tooltip-text="<%= t('.denied') %>"></i><% end %>
50+
<% if m.is_moderator? %><i class="fas fa-user-shield muted tooltip-basic" data-tooltip-text="<%= t('.moderator') %>"></i><% end %>
51+
<% if m.receive_emails %><i class='far fa-envelope muted tooltip-basic' data-tooltip-text="<%= Membership.human_attribute_name(:receive_emails) %>"></i><% end %>
52+
</li>
53+
<% end %>
54+
</ul>
3155
</td>
32-
<td><%= user.email %></td>
33-
<td><%= user.groups.map(&:name).join(",") %></td>
3456

3557
<td>
3658
<% if can? :edit, user %>

config/locales/de.yml

+9
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,10 @@ de:
703703
membership_promoted: Mitglied wurde erfolgreich zum Leiter befördert.
704704
membership_promoted_failure: Mitglied konnte nicht zum Leider befördert werden.
705705
membership_unknown_action: Unbekannte Mitgliedsaktion gesendet.
706+
moderator_mailer:
707+
items_pending:
708+
a_submission_is_pending_moderation: A submission is pending moderation.
709+
concerto_submission_pending_approval: Concerto Submission Pending Approval
706710
missing_default_type: Standard Beitragstyp fehlt
707711
my_model: 'Mein %{model}'
708712
name: Name
@@ -1008,7 +1012,12 @@ de:
10081012
options: Optionen
10091013
provide_details: Einstellungen vornehmen
10101014
index:
1015+
denied: Enfernt
1016+
leader: Leiter
1017+
moderator: Moderator
10111018
name: Name
1019+
pending: Ausstehend
1020+
system_admin: Administrator
10121021
show_body:
10131022
admin: Admin
10141023
content: Beiträge

config/locales/en.yml

+9
Original file line numberDiff line numberDiff line change
@@ -743,6 +743,10 @@ en:
743743
membership_promoted_failure: Member was not successfully promoted to group leader
744744
membership_unknown_action: Unknown Membership action submitted.
745745
missing_default_type: Missing Default Content Type
746+
moderator_mailer:
747+
items_pending:
748+
a_submission_is_pending_moderation: A submission is pending moderation.
749+
concerto_submission_pending_approval: Concerto Submission Pending Approval
746750
my_model: My %{model}
747751
name: name
748752
new_model: New %{model}
@@ -1089,7 +1093,12 @@ en:
10891093
options: Options
10901094
provide_details: Provide Details
10911095
index:
1096+
denied: Denied
1097+
leader: Leader
1098+
moderator: Moderator
10921099
name: Name
1100+
pending: Pending
1101+
system_admin: System Admin
10931102
show_body:
10941103
admin: Admin
10951104
content: Content

0 commit comments

Comments
 (0)