Merge pull request #2792 from consul/system_emails

System emails
This commit is contained in:
Alberto
2018-07-26 00:01:07 +02:00
committed by GitHub
14 changed files with 277 additions and 43 deletions

View File

@@ -0,0 +1,37 @@
class Admin::SystemEmailsController < Admin::BaseController
before_action :load_system_email, only: [:view, :preview_pending]
def index
@system_emails = {
proposal_notification_digest: %w(view preview_pending)
}
end
def view
case @system_email
when "proposal_notification_digest"
@notifications = Notification.where(notifiable_type: "ProposalNotification").limit(2)
@subject = t('mailers.proposal_notification_digest.title', org_name: Setting['org_name'])
end
end
def preview_pending
case @system_email
when "proposal_notification_digest"
@previews = ProposalNotification.where(id: unsent_proposal_notifications_ids)
.page(params[:page])
end
end
private
def load_system_email
@system_email = params[:system_email_id]
end
def unsent_proposal_notifications_ids
Notification.where(notifiable_type: "ProposalNotification", emailed_at: nil)
.group(:notifiable_id).count.keys
end
end

View File

@@ -79,21 +79,24 @@
</li>
<% end %>
<% newsletters_notifications_sections = %w(newsletters emails_download admin_notifications) %>
<% newsletters_menu_active = newsletters_notifications_sections.include?(controller_name) %>
<li class="section-title" <%= "class=active" if newsletters_menu_active %>>
<% messages_sections = %w(newsletters emails_download admin_notifications system_emails) %>
<% messages_menu_active = messages_sections.include?(controller_name) %>
<li class="section-title" <%= "class=is-active" if messages_menu_active %>>
<a href="#">
<span class="icon-zip"></span>
<strong><%= t("admin.menu.newsletters_and_notifications") %></strong>
<strong><%= t("admin.menu.messaging_users") %></strong>
</a>
<ul id="newsletters_and_notifications_menu" <%= "class=is-active" if newsletters_menu_active %>>
<li <%= "class=active" if controller_name == "newsletters" %>>
<ul id="messaging_users_menu" <%= "class=is-active" if messages_menu_active %>>
<li <%= "class=is-active" if controller_name == "newsletters" %>>
<%= link_to t("admin.menu.newsletters"), admin_newsletters_path %>
</li>
<li <%= "class=active" if controller_name == "admin_notifications" %>>
<li <%= "class=is-active" if controller_name == "admin_notifications" %>>
<%= link_to t("admin.menu.admin_notifications"), admin_admin_notifications_path %>
</li>
<li <%= "class=active" if controller_name == "emails_download" %>>
<li <%= "class=is-active" if controller_name == "system_emails" %>>
<%= link_to t("admin.menu.system_emails"), admin_system_emails_path %>
</li>
<li <%= "class=is-active" if controller_name == "emails_download" %>>
<%= link_to t("admin.menu.emails_download"), admin_emails_download_index_path %>
</li>
</ul>

View File

@@ -0,0 +1,34 @@
<h2 class="inline-block"><%= t("admin.menu.system_emails") %></h2>
<table id="system_emails">
<thead>
<tr>
<th><%= t("admin.shared.title") %></th>
<th><%= t("admin.shared.description") %></th>
<th class="small-5 text-right"><%= t("admin.shared.actions") %></th>
</tr>
</thead>
<tbody>
<% @system_emails.each do |system_email_title, system_email_actions| %>
<tr id="<%= system_email_title %>" class="system_email">
<td>
<%= t("admin.system_emails.#{system_email_title}.title") %>
</td>
<td>
<%= t("admin.system_emails.#{system_email_title}.description") %>
</td>
<td class="text-right">
<% if system_email_actions.include?('view') %>
<%= link_to t("admin.shared.view"), admin_system_email_view_path(system_email_title),
class: "button hollow" %>
<% end %>
<% if system_email_actions.include?('preview_pending') %>
<%= link_to t("admin.system_emails.preview_pending.action"),
admin_system_email_preview_pending_path(system_email_title),
class: "button" %>
<% end %>
</td>
</tr>
<% end %>
</tbody>
</table>

View File

@@ -0,0 +1,16 @@
<%= back_link_to admin_system_emails_path %>
<% system_email_name = t("admin.system_emails.#{@system_email}.title") %>
<h2><%= t("admin.system_emails.preview_pending.preview_of", name: system_email_name) %></h2>
<div class="small-12 column">
<h4><%= t("admin.system_emails.preview_pending.pending_to_be_sent") %></h4>
<p><%= t("admin.system_emails.#{@system_email}.preview_detail") %></p>
<% @previews.each do |preview| %>
<%= render partial: "admin/system_emails/preview_pending/#{@system_email}",
locals: { preview: preview } %>
<% end %>
</div>
<%= paginate @previews %>

View File

@@ -0,0 +1,33 @@
<% if preview.proposal.present? %>
<div class="callout highlight">
<div class="row">
<div class="small-12 medium-6 column">
<strong><%= t("admin.shared.proposal") %></strong><br>
<%= link_to preview.proposal.title, proposal_url(preview.proposal) %>
</div>
<div class="small-12 medium-6 column">
<strong><%= t("admin.shared.title") %></strong><br>
<%= link_to preview.title, proposal_url(preview.proposal, anchor: "tab-notifications") %>
</div>
</div>
<div class="row">
<div class="small-12 medium-6 column">
<strong><%= t("admin.shared.author") %></strong><br>
<%= preview.proposal.author&.username || '-' %>
</div>
<div class="small-12 medium-6 column">
<strong><%= t("admin.shared.created_at") %></strong><br>
<%= l(preview.created_at, format: :datetime) %>
</div>
</div>
</div>
<div class="row">
<div class="column">
<strong><%= t("admin.shared.content") %></strong>
<p class="help-text" id="phase-description-help-text">
<%= preview.body %>
</p>
</div>
</div>
<% end %>

View File

@@ -0,0 +1,36 @@
<%= back_link_to admin_system_emails_path %>
<h2><%= t("admin.system_emails.#{@system_email}.title") %></h2>
<div class="small-12 column">
<div class="callout highlight">
<div class="row">
<div class="small-12 medium-4 column">
<strong><%= t("admin.newsletters.show.from") %></strong><br>
<%= Setting['mailer_from_address'] %>
</div>
<div class="small-12 medium-8 column">
<strong><%= t("admin.newsletters.show.subject") %></strong><br>
<%= @subject %>
</div>
</div>
</div>
<strong><%= t("admin.newsletters.show.body") %></strong>
<p class="help-text" id="phase-description-help-text">
<%= t("admin.newsletters.show.body_help_text") %>
</p>
<div class="newsletter-body-content">
<%= render file: "app/views/layouts/_mailer_header.html.erb" %>
<table cellpadding="0" cellspacing="0" border="0" style="background: #fff; margin: 0 auto; max-width: 700px; width:100%;">
<tbody>
<tr>
<%= render file: "app/views/mailer/#{@system_email}.html.erb" %>
</tr>
</tbody>
</table>
<%= render file: "app/views/layouts/_mailer_footer.html.erb" %>
</div>
</div>

View File

@@ -22,7 +22,7 @@
<tr>
<td style="padding-bottom: 20px; padding-left: 10px;">
<p style="font-family: 'Open Sans','Helvetica Neue',arial,sans-serif;font-size: 20px;font-weight: bold;line-height: 24px; margin: 0;">
<%= link_to notification.notifiable.title, notification_url(notification), style: "color: #2895F1; text-decoration: none;" %>
<%= link_to notification.notifiable.title, proposal_url(notification.notifiable.proposal, anchor: "tab-notifications"), style: "color: #2895F1; text-decoration: none;" %>
</p>
<p style="font-family: 'Open Sans','Helvetica Neue',arial,sans-serif;font-size: 14px;font-weight: normal;line-height: 24px; margin-top: 0; color: #cccccc;">
<%= notification.notifiable.proposal.title %>&nbsp;&bull;&nbsp;

View File

@@ -518,9 +518,10 @@ en:
administrators: Administrators
managers: Managers
moderators: Moderators
newsletters_and_notifications: Newsletters & Notifications
messaging_users: Messages to users
newsletters: Newsletters
admin_notifications: Notifications
system_emails: System Emails
emails_download: Emails download
valuators: Valuators
poll_officers: Poll officers
@@ -649,6 +650,15 @@ en:
preview_guide: "This is how the users will see the notification:"
sent_guide: "This is how the users see the notification:"
send_alert: Are you sure you want to send this notification to %{n} users?
system_emails:
preview_pending:
action: Preview Pending
preview_of: Preview of %{name}
pending_to_be_sent: This is the content pending to be sent
proposal_notification_digest:
title: Proposal Notification Digest
description: Gathers all proposal notifications for an user in a single message, to avoid too much emails.
preview_detail: Users will only recieve notifications from the proposals they are following
emails_download:
index:
title: Emails download
@@ -1045,6 +1055,11 @@ en:
image: Image
show_image: Show image
moderated_content: "Check the content moderated by the moderators, and confirm if the moderation has been done correctly."
view: View
proposal: Proposal
author: Author
content: Content
created_at: Created at
spending_proposals:
index:
geozone_filter_all: All zones

View File

@@ -53,18 +53,3 @@ en:
recounting_poll: "Recounting Poll"
expired_poll_without_stats: "Expired Poll without Stats & Results"
expired_poll_with_stats: "Expired Poll with Stats & Results"
admin_notifications:
internal_link:
title: 'Do you have a proposal?'
body: 'Remember you can create a proposal with your ideas and people will discuss & support it.'
link: '/proposals'
external_link:
title: Help us translate consul
body: 'If you are proficient in a language, please help us translate consul!.'
link: 'https://crwd.in/consul'
without_link:
title: 'You can now geolocate proposals & investments'
body: 'When you create a proposal or investment you now can specify a point on a map'
not_sent:
title: 'We are closing the Participatory Budget!!'
body: 'Hurry up and create a last proposal before it ends next in few days!'

View File

@@ -519,9 +519,10 @@ es:
administrators: Administradores
managers: Gestores
moderators: Moderadores
newsletters_and_notifications: Newsletters & Notificaciones
messaging_users: Mensajes a usuarios
newsletters: Newsletters
admin_notifications: Notificaciones
system_emails: Emails del sistema
emails_download: Descarga de emails
valuators: Evaluadores
poll_officers: Presidentes de mesa
@@ -650,6 +651,15 @@ es:
preview_guide: "Así es como los usuarios verán la notificación:"
sent_guide: "Así es como los usuarios ven la notificación:"
send_alert: ¿Estás seguro/a de que quieres enviar esta notificación a %{n} usuarios?
system_emails:
preview_pending:
action: Previsualizar Pendientes
preview_of: Vista previa de %{name}
pending_to_be_sent: Este es todo el contenido pendiente de enviar
proposal_notification_digest:
title: Resumen de Notificationes de Propuestas
description: Reune todas las notificaciones de propuestas en un único mensaje, para evitar demasiados emails.
preview_detail: Los usuarios sólo recibirán las notificaciones de aquellas propuestas que siguen.
emails_download:
index:
title: Descarga de emails
@@ -1046,6 +1056,11 @@ es:
image: Imagen
show_image: Mostrar imagen
moderated_content: "Revisa el contenido moderado por los moderadores, y confirma si la moderación se ha realizado correctamente."
view: Ver
proposal: Propuesta
author: Autor
content: Contenido
created_at: Fecha de creación
spending_proposals:
index:
geozone_filter_all: Todos los ámbitos de actuación

View File

@@ -53,18 +53,3 @@ es:
recounting_poll: "Votación en Recuento"
expired_poll_without_stats: "Votación Finalizada (sin Estadísticas o Resultados)"
expired_poll_with_stats: "Votación Finalizada (con Estadísticas y Resultado)"
admin_notifications:
internal_link:
title: 'Tienes una propuesta?'
body: 'Recuerda que puedes crear propuestas y los ciudadanos las debatirán y apoyarán.'
link: '/proposals'
external_link:
title: 'Ayúdanos a traducir CONSUL'
body: 'Si dominas un idioma, ayúdanos a completar su traducción en CONSUL.'
link: 'https://crwd.in/consul'
without_link:
title: 'Ahora puedes geolocalizar propuestas y proyectos de inversión'
body: 'Cuando crees una propuesta o proyecto de inversión podrás especificar su localización en el mapa'
not_sent:
title: 'Últimos días para crear proyectos de Presupuestos Participativos'
body: 'Quedan pocos dias para que se cierre el plazo de presentación de proyectos de inversión para los presupuestos participativos!'

View File

@@ -165,6 +165,11 @@ namespace :admin do
end
end
resources :system_emails, only: [:index] do
get :view
get :preview_pending
end
resources :emails_download, only: :index do
get :generate_csv, on: :collection
end

View File

@@ -0,0 +1,70 @@
require 'rails_helper'
feature "System Emails" do
background do
admin = create(:administrator)
login_as(admin.user)
end
context "Index" do
scenario "Lists all system emails with correct actions" do
visit admin_system_emails_path
within('#proposal_notification_digest') do
expect(page).to have_link('View')
end
end
end
context "View" do
scenario "#proposal_notification_digest" do
proposal_a = create(:proposal, title: 'Proposal A')
proposal_b = create(:proposal, title: 'Proposal B')
proposal_notification_a = create(:proposal_notification, proposal: proposal_a,
title: 'Proposal A Title',
body: 'Proposal A Notification Body')
proposal_notification_b = create(:proposal_notification, proposal: proposal_b,
title: 'Proposal B Title',
body: 'Proposal B Notification Body')
create(:notification, notifiable: proposal_notification_a)
create(:notification, notifiable: proposal_notification_b)
visit admin_system_email_view_path('proposal_notification_digest')
expect(page).to have_content('Proposal notifications in')
expect(page).to have_link('Proposal A Title', href: proposal_url(proposal_a,
anchor: 'tab-notifications'))
expect(page).to have_link('Proposal B Title', href: proposal_url(proposal_b,
anchor: 'tab-notifications'))
expect(page).to have_content('Proposal A Notification Body')
expect(page).to have_content('Proposal B Notification Body')
end
end
context "Preview Pending" do
scenario "#proposal_notification_digest" do
proposal_a = create(:proposal, title: 'Proposal A')
proposal_b = create(:proposal, title: 'Proposal B')
proposal_notification_a = create(:proposal_notification, proposal: proposal_a,
title: 'Proposal A Title',
body: 'Proposal A Notification Body')
proposal_notification_b = create(:proposal_notification, proposal: proposal_b,
title: 'Proposal B Title',
body: 'Proposal B Notification Body')
create(:notification, notifiable: proposal_notification_a, emailed_at: nil)
create(:notification, notifiable: proposal_notification_b, emailed_at: nil)
visit admin_system_email_preview_pending_path('proposal_notification_digest')
expect(page).to have_content('This is the content pending to be sent')
expect(page).to have_link('Proposal A', href: proposal_url(proposal_a))
expect(page).to have_link('Proposal B', href: proposal_url(proposal_b))
expect(page).to have_link('Proposal A Title', href: proposal_url(proposal_a,
anchor: 'tab-notifications'))
expect(page).to have_link('Proposal B Title', href: proposal_url(proposal_b,
anchor: 'tab-notifications'))
end
end
end

View File

@@ -306,14 +306,14 @@ feature 'Emails' do
expect(email).to have_body_text(notification1.notifiable.body)
expect(email).to have_body_text(proposal1.author.name)
expect(email).to have_body_text(/#{notification_path(notification1)}/)
expect(email).to have_body_text(/#{proposal_path(proposal1, anchor: 'tab-notifications')}/)
expect(email).to have_body_text(/#{proposal_path(proposal1, anchor: 'comments')}/)
expect(email).to have_body_text(/#{proposal_path(proposal1, anchor: 'social-share')}/)
expect(email).to have_body_text(proposal2.title)
expect(email).to have_body_text(notification2.notifiable.title)
expect(email).to have_body_text(notification2.notifiable.body)
expect(email).to have_body_text(/#{notification_path(notification2)}/)
expect(email).to have_body_text(/#{proposal_path(proposal2, anchor: 'tab-notifications')}/)
expect(email).to have_body_text(/#{proposal_path(proposal2, anchor: 'comments')}/)
expect(email).to have_body_text(/#{proposal_path(proposal2, anchor: 'social-share')}/)
expect(email).to have_body_text(proposal2.author.name)