From d215b23272bc035473d4d686d57f81bb5e99f412 Mon Sep 17 00:00:00 2001 From: Victor Costa Date: Tue, 9 Jun 2015 15:39:25 -0300 Subject: [PATCH] Option to choose template to send email to members --- app/controllers/my_profile/email_templates_controller.rb | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ app/controllers/public/profile_controller.rb | 1 + app/models/email_template.rb | 2 ++ app/models/environment.rb | 4 ++++ app/models/profile.rb | 6 ++++++ app/views/email_templates/_form.html.erb | 30 ++++++++++++++++++++++++++++++ app/views/email_templates/edit.html.erb | 3 +++ app/views/email_templates/index.html.erb | 23 +++++++++++++++++++++++ app/views/email_templates/new.html.erb | 3 +++ app/views/email_templates/show.html.erb | 5 +++++ app/views/profile/send_mail.html.erb | 6 ++++++ app/views/profile_editor/index.html.erb | 2 ++ public/javascripts/application.js | 1 + public/javascripts/email_templates.js | 10 ++++++++++ public/proposal-app | 1 + public/stylesheets/application.css | 4 ++++ public/stylesheets/email-templates.css | 15 +++++++++++++++ test/functional/email_templates_controller_test.rb | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ test/functional/profile_editor_controller_test.rb | 11 +++++++++++ test/unit/email_template_test.rb | 8 ++++---- 20 files changed, 262 insertions(+), 4 deletions(-) create mode 100644 app/controllers/my_profile/email_templates_controller.rb create mode 100644 app/views/email_templates/_form.html.erb create mode 100644 app/views/email_templates/edit.html.erb create mode 100644 app/views/email_templates/index.html.erb create mode 100644 app/views/email_templates/new.html.erb create mode 100644 app/views/email_templates/show.html.erb create mode 100644 public/javascripts/email_templates.js create mode 160000 public/proposal-app create mode 100644 public/stylesheets/email-templates.css create mode 100644 test/functional/email_templates_controller_test.rb diff --git a/app/controllers/my_profile/email_templates_controller.rb b/app/controllers/my_profile/email_templates_controller.rb new file mode 100644 index 0000000..26e3eaf --- /dev/null +++ b/app/controllers/my_profile/email_templates_controller.rb @@ -0,0 +1,63 @@ +class EmailTemplatesController < MyProfileController + + protect 'send_mail_to_members', :profile + + def index + @email_templates = profile.email_templates + end + + def show + @email_template = profile.email_templates.find(params[:id]) + + respond_to do |format| + format.html # show.html.erb + format.json { render json: @email_template } + end + end + + def show_parsed + @email_template = profile.email_templates.find(params[:id]) + template_params = {:profile => profile, :environment => environment} + render json: {:parsed_body => @email_template.parsed_body(template_params), :parsed_subject => @email_template.parsed_subject(template_params)} + end + + def new + @email_template = profile.email_templates.build + end + + def edit + @email_template = profile.email_templates.find(params[:id]) + end + + def create + @email_template = profile.email_templates.build(params[:email_template], :owner => profile) + + if @email_template.save + session[:notice] = _('Email template was successfully created.') + redirect_to url_for(:action => :index) + else + render action: "new" + end + end + + def update + @email_template = profile.email_templates.find(params[:id]) + + if @email_template.update_attributes(params[:email_template]) + session[:notice] = _('Email template was successfully updated.') + redirect_to url_for(:action => :index) + else + render action: "edit" + end + end + + def destroy + @email_template = profile.email_templates.find(params[:id]) + @email_template.destroy + + respond_to do |format| + format.html { redirect_to url_for(:action => :index)} + format.json { head :no_content } + end + end +end diff --git a/app/controllers/public/profile_controller.rb b/app/controllers/public/profile_controller.rb index da07102..0e212c5 100644 --- a/app/controllers/public/profile_controller.rb +++ b/app/controllers/public/profile_controller.rb @@ -353,6 +353,7 @@ class ProfileController < PublicController def send_mail @mailing = profile.mailings.build(params[:mailing]) + @email_templates = profile.email_templates if request.post? @mailing.locale = locale @mailing.person = user diff --git a/app/models/email_template.rb b/app/models/email_template.rb index bc0efaa..0b3e42b 100644 --- a/app/models/email_template.rb +++ b/app/models/email_template.rb @@ -4,6 +4,8 @@ class EmailTemplate < ActiveRecord::Base attr_accessible :template_type, :subject, :body, :owner, :name + validates_presence_of :name + def parsed_body(params) @parsed_body ||= parse(body, params) end diff --git a/app/models/environment.rb b/app/models/environment.rb index 321551d..a80323f 100644 --- a/app/models/environment.rb +++ b/app/models/environment.rb @@ -982,6 +982,10 @@ class Environment < ActiveRecord::Base self.licenses.any? end + def to_liquid + HashWithIndifferentAccess.new :name => name + end + private def default_language_available diff --git a/app/models/profile.rb b/app/models/profile.rb index 7c5a0e9..d0fee79 100644 --- a/app/models/profile.rb +++ b/app/models/profile.rb @@ -151,6 +151,8 @@ class Profile < ActiveRecord::Base has_many :comments_received, :class_name => 'Comment', :through => :articles, :source => :comments + has_many :email_templates, :foreign_key => :owner_id + # Although this should be a has_one relation, there are no non-silly names for # a foreign key on article to reference the template to which it is # welcome_page... =P @@ -471,6 +473,10 @@ class Profile < ActiveRecord::Base self.articles.find(:all, options) end + def to_liquid + HashWithIndifferentAccess.new :name => name, :identifier => identifier + end + class << self # finds a profile by its identifier. This method is a shortcut to diff --git a/app/views/email_templates/_form.html.erb b/app/views/email_templates/_form.html.erb new file mode 100644 index 0000000..72f5ed9 --- /dev/null +++ b/app/views/email_templates/_form.html.erb @@ -0,0 +1,30 @@ +<%= form_for(@email_template, :url => {:controller => :email_templates, :action => @email_template.persisted? ? :update : :create, :id => @email_template.id}) do |f| %> + + <%= error_messages_for :email_template if @email_template.errors.any? %> + +
+
+ <%= labelled_form_field(_('Template Name:'), f.text_field(:name)) %> + <%= labelled_form_field(_('Subject:'), f.text_field(:subject)) %> +
+
+ +
+ <%= _('The following parameters may be used in subject and body:') %> +
+
+ {{profile.name}}, {{profile.identifier}}, {{environment.name}} +
+
+ <%= render :file => 'shared/tiny_mce' %> + <%= labelled_form_field(_('Body:'), f.text_area(:body, :class => 'mceEditor')) %> +
+ +
+ <%= submit_button(:save, _('Save')) %> + <%= button(:back, _('Back'), :controller => :email_templates) %> +
+ +<% end %> diff --git a/app/views/email_templates/edit.html.erb b/app/views/email_templates/edit.html.erb new file mode 100644 index 0000000..0a9b078 --- /dev/null +++ b/app/views/email_templates/edit.html.erb @@ -0,0 +1,3 @@ +

Editing Email Template

+ +<%= render 'form' %> diff --git a/app/views/email_templates/index.html.erb b/app/views/email_templates/index.html.erb new file mode 100644 index 0000000..3f191b7 --- /dev/null +++ b/app/views/email_templates/index.html.erb @@ -0,0 +1,23 @@ +

<%= _('Email Templates') %>

+ + + + + + + +<% @email_templates.each do |email_template| %> + + + + +<% end %> +
<%= _('Name') %>
<%= email_template.name %> + <%= link_to 'Edit', url_for(:controller => :email_templates, :action => :edit, :id => email_template.id) %> + <%= link_to 'Destroy', url_for(:controller => :email_templates, :action => :destroy, :id => email_template.id), method: :delete, data: { confirm: 'Are you sure?' } %> +
+ +
+ +<%= button(:new, _('New template'), :controller => :email_templates, :action => :new) %> +<%= button(:back, _('Back to control panel'), :controller => :profile_editor) %> diff --git a/app/views/email_templates/new.html.erb b/app/views/email_templates/new.html.erb new file mode 100644 index 0000000..739ff6b --- /dev/null +++ b/app/views/email_templates/new.html.erb @@ -0,0 +1,3 @@ +

New Email Template

+ +<%= render 'form' %> diff --git a/app/views/email_templates/show.html.erb b/app/views/email_templates/show.html.erb new file mode 100644 index 0000000..6661671 --- /dev/null +++ b/app/views/email_templates/show.html.erb @@ -0,0 +1,5 @@ +

<%= notice %>

+ + +<%= link_to 'Edit', url_for(:controller => :email_templates, :action => :edit, :id => @email_template.id) %> | +<%= link_to 'Back', url_for(:controller => :email_templates) %> diff --git a/app/views/profile/send_mail.html.erb b/app/views/profile/send_mail.html.erb index 86cdead..b206210 100644 --- a/app/views/profile/send_mail.html.erb +++ b/app/views/profile/send_mail.html.erb @@ -4,6 +4,12 @@ <%= error_messages_for :mailing %> +
+ <% if @email_templates.present? %> + <%= labelled_form_field(_('Select a template:'), select_tag(:template, options_from_collection_for_select(@email_templates, :id, :name), :include_blank => true, 'data-url' => url_for(:controller => 'email_templates', :action => 'show_parsed'))) %> + <% end %> +
+ <%= form_for :mailing, :url => {:action => 'send_mail'}, :html => {:id => 'mailing-form'} do |f| %> <%= labelled_form_field(_('Subject:'), f.text_field(:subject)) %> diff --git a/app/views/profile_editor/index.html.erb b/app/views/profile_editor/index.html.erb index 7d3db97..81ed334 100644 --- a/app/views/profile_editor/index.html.erb +++ b/app/views/profile_editor/index.html.erb @@ -72,6 +72,8 @@ <%= control_panel_button(_('Edit welcome page'), 'welcome-page', :action => 'welcome_page') if has_welcome_page %> + <%= control_panel_button(_('Email Templates'), 'email-templates', :controller => :email_templates) if profile.organization? %> + <% @plugins.dispatch(:control_panel_buttons).each do |button| %> <%= control_panel_button(button[:title], button[:icon], button[:url], button[:html_options]) %> <% end %> diff --git a/public/javascripts/application.js b/public/javascripts/application.js index 3206d8d..3fb3193 100644 --- a/public/javascripts/application.js +++ b/public/javascripts/application.js @@ -28,6 +28,7 @@ *= require catalog.js *= require autogrow.js *= require require_login.js +*= require email_templates.js */ // scope for noosfero stuff diff --git a/public/javascripts/email_templates.js b/public/javascripts/email_templates.js new file mode 100644 index 0000000..87a35d8 --- /dev/null +++ b/public/javascripts/email_templates.js @@ -0,0 +1,10 @@ +jQuery(document).ready(function($) { + $('.template-selection select').change(function() { + if(!$(this).val()) return; + + $.getJSON($(this).data('url'), {id: $(this).val()}, function(data) { + $('#mailing-form #mailing_subject').val(data.parsed_subject); + $('#mailing-form .mceEditor').val(data.parsed_body); + }); + }); +}); diff --git a/public/proposal-app b/public/proposal-app new file mode 160000 index 0000000..e7ad784 --- /dev/null +++ b/public/proposal-app @@ -0,0 +1 @@ +Subproject commit e7ad7849b3ef685639d4c5c0bef7b323255e2afa diff --git a/public/stylesheets/application.css b/public/stylesheets/application.css index 89d9a67..d01a8af 100644 --- a/public/stylesheets/application.css +++ b/public/stylesheets/application.css @@ -14,6 +14,7 @@ * views specifics *= require chat *= require search + *= require email-templates */ /* browser fixes */ @@ -4658,6 +4659,9 @@ h1#agenda-title { .controller-profile_editor a.control-panel-design-editor { background-image: url(../images/control-panel/preferences-desktop-wallpaper.png) } +.controller-profile_editor a.control-panel-email-templates { + background-image: url(../images/control-panel/email.png) +} .controller-profile_editor .msie6 a.control-panel-design-editor { background-image: url(../images/control-panel/preferences-desktop-wallpaper.gif) } diff --git a/public/stylesheets/email-templates.css b/public/stylesheets/email-templates.css new file mode 100644 index 0000000..6cf4b4b --- /dev/null +++ b/public/stylesheets/email-templates.css @@ -0,0 +1,15 @@ +.template-fields .header-fields, .template-fields .available-params { + width: 48%; + display: inline-block; +} +.template-fields .available-params .values { + color: rgb(111, 111, 111); +} +.template-fields .available-params .reference { + text-align: right; +} +.template-fields .available-params .reference a { + color: rgb(32, 101, 229); + text-decoration: none; + font-size: 10px; +} diff --git a/test/functional/email_templates_controller_test.rb b/test/functional/email_templates_controller_test.rb new file mode 100644 index 0000000..5718a1b --- /dev/null +++ b/test/functional/email_templates_controller_test.rb @@ -0,0 +1,68 @@ +require 'test_helper' + +class EmailTemplatesControllerTest < ActionController::TestCase + + setup do + @profile = fast_create(Community) + @email_template = EmailTemplate.create!(:name => 'template', :owner => @profile) + @person = create_user_with_permission('templatemanager', 'send_mail_to_members', @profile) + login_as(@person.user.login) + end + + attr_accessor :profile, :person + + test "should get index" do + get :index, :profile => profile.identifier + assert_response :success + assert_not_nil assigns(:email_templates) + end + + test "should get new" do + get :new, :profile => profile.identifier + assert_response :success + end + + test "should create email_template" do + assert_difference('EmailTemplate.count') do + post :create, email_template: { :name => 'test' }, :profile => profile.identifier + end + + assert_redirected_to url_for(:action => :index) + end + + test "should show email_template" do + get :show, id: @email_template, :profile => profile.identifier + assert_response :success + end + + test "should get edit" do + get :edit, id: @email_template, :profile => profile.identifier + assert_response :success + end + + test "should update email_template" do + put :update, id: @email_template, email_template: { }, :profile => profile.identifier + assert_redirected_to url_for(:action => :index) + end + + test "should destroy email_template" do + assert_difference('EmailTemplate.count', -1) do + delete :destroy, id: @email_template, :profile => profile.identifier + end + + assert_redirected_to url_for(:action => :index) + end + + test "should get parsed template" do + environment = Environment.default + @email_template.subject = '{{profile.name}} - {{profile.identifier}}' + @email_template.body = '{{profile.name}} - {{profile.identifier}} - {{environment.name}}' + @email_template.save! + get :show_parsed, id: @email_template, :profile => profile.identifier + assert_response :success + json_response = ActiveSupport::JSON.decode(@response.body) + assert_equal "#{profile.name} - #{profile.identifier}", json_response['parsed_subject'] + assert_equal "#{profile.name} - #{profile.identifier} - #{environment.name}", json_response['parsed_body'] + end + +end diff --git a/test/functional/profile_editor_controller_test.rb b/test/functional/profile_editor_controller_test.rb index fde38e3..3c3aebb 100644 --- a/test/functional/profile_editor_controller_test.rb +++ b/test/functional/profile_editor_controller_test.rb @@ -626,6 +626,17 @@ class ProfileEditorControllerTest < ActionController::TestCase assert_tag :tag => 'a', :attributes => { :href => '/myprofile/default_user/cms' } end + should 'display email template link for organizations in control panel' do + profile = fast_create(Organization) + get :index, :profile => profile.identifier + assert_tag :tag => 'a', :attributes => { :href => "/myprofile/#{profile.identifier}/email_templates" } + end + + should 'not display email template link in control panel for person' do + get :index, :profile => profile.identifier + assert_no_tag :tag => 'a', :attributes => { :href => "/myprofile/#{profile.identifier}/email_templates" } + end + should 'offer to create blog in control panel' do get :index, :profile => profile.identifier assert_tag :tag => 'a', :attributes => { :href => "/myprofile/default_user/cms/new?type=Blog" } diff --git a/test/unit/email_template_test.rb b/test/unit/email_template_test.rb index 7706cc8..d0f8e97 100644 --- a/test/unit/email_template_test.rb +++ b/test/unit/email_template_test.rb @@ -3,10 +3,10 @@ require_relative "../test_helper" class EmailTemplateTest < ActiveSupport::TestCase should 'filter templates by type' do - EmailTemplate.create!(:template_type => :type1, :subject => 'template1') - EmailTemplate.create!(:template_type => :type2, :subject => 'template2') - EmailTemplate.create!(:template_type => :type2, :subject => 'template3') - assert_equal ['template2', 'template3'], EmailTemplate.find_all_by_template_type(:type2).map(&:subject) + EmailTemplate.create!(:template_type => :type1, :name => 'template1') + EmailTemplate.create!(:template_type => :type2, :name => 'template2') + EmailTemplate.create!(:template_type => :type2, :name => 'template3') + assert_equal ['template2', 'template3'], EmailTemplate.find_all_by_template_type(:type2).map(&:name) end should 'parse body using params' do -- libgit2 0.21.2