effective_polls 0.0.1 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +1 -1
  3. data/README.md +51 -20
  4. data/app/controllers/admin/poll_notifications_controller.rb +1 -1
  5. data/app/controllers/admin/poll_questions_controller.rb +1 -1
  6. data/app/controllers/admin/polls_controller.rb +1 -1
  7. data/app/controllers/effective/ballots_controller.rb +1 -1
  8. data/app/datatables/admin/effective_polls_datatable.rb +2 -2
  9. data/app/mailers/effective/polls_mailer.rb +58 -10
  10. data/app/models/effective/ballot_response.rb +6 -6
  11. data/app/models/effective/poll.rb +9 -18
  12. data/app/models/effective/poll_notification.rb +18 -18
  13. data/app/models/effective/poll_question.rb +11 -10
  14. data/app/views/admin/poll_notifications/_form.html.haml +24 -37
  15. data/app/views/admin/poll_notifications/_form_poll_reminder.html.haml +8 -0
  16. data/app/views/admin/poll_notifications/_form_poll_upcoming_reminder.html.haml +8 -0
  17. data/app/views/admin/poll_notifications/_form_poll_when_poll_ends.html.haml +3 -0
  18. data/app/views/admin/poll_notifications/_form_poll_when_poll_starts.html.haml +3 -0
  19. data/app/views/admin/poll_questions/_form.html.haml +15 -15
  20. data/app/views/admin/polls/_form.html.haml +5 -1
  21. data/app/views/admin/polls/_form_poll.html.haml +2 -2
  22. data/app/views/effective/ballot_responses/fields/_date.html.haml +2 -1
  23. data/app/views/effective/ballot_responses/fields/_email.html.haml +2 -1
  24. data/app/views/effective/ballot_responses/fields/_number.html.haml +2 -1
  25. data/app/views/effective/ballot_responses/fields/{_select_upto_1.html.haml → _select_up_to_1.html.haml} +0 -0
  26. data/app/views/effective/ballot_responses/fields/{_select_upto_2.html.haml → _select_up_to_2.html.haml} +0 -0
  27. data/app/views/effective/ballot_responses/fields/{_select_upto_3.html.haml → _select_up_to_3.html.haml} +0 -0
  28. data/app/views/effective/ballot_responses/fields/{_select_upto_4.html.haml → _select_up_to_4.html.haml} +0 -0
  29. data/app/views/effective/ballot_responses/fields/{_select_upto_5.html.haml → _select_up_to_5.html.haml} +0 -0
  30. data/app/views/effective/ballot_responses/responses/{_select_upto_1.html.haml → _select_up_to_1.html.haml} +0 -0
  31. data/app/views/effective/ballot_responses/responses/{_select_upto_2.html.haml → _select_up_to_2.html.haml} +0 -0
  32. data/app/views/effective/ballot_responses/responses/{_select_upto_3.html.haml → _select_up_to_3.html.haml} +0 -0
  33. data/app/views/effective/ballot_responses/responses/{_select_upto_4.html.haml → _select_up_to_4.html.haml} +0 -0
  34. data/app/views/effective/ballot_responses/responses/{_select_upto_5.html.haml → _select_up_to_5.html.haml} +0 -0
  35. data/app/views/effective/ballots/_ballot.html.haml +2 -2
  36. data/app/views/effective/ballots/start.html.haml +1 -1
  37. data/app/views/effective/ballots/submit.html.haml +1 -1
  38. data/app/views/effective/ballots/vote.html.haml +1 -1
  39. data/app/views/effective/poll_results/_results.html.haml +1 -1
  40. data/app/views/effective/poll_results/results/{_select_upto_1.html.haml → _select_up_to_1.html.haml} +0 -0
  41. data/app/views/effective/poll_results/results/{_select_upto_2.html.haml → _select_up_to_2.html.haml} +0 -0
  42. data/app/views/effective/poll_results/results/{_select_upto_3.html.haml → _select_up_to_3.html.haml} +0 -0
  43. data/app/views/effective/poll_results/results/{_select_upto_4.html.haml → _select_up_to_4.html.haml} +0 -0
  44. data/app/views/effective/poll_results/results/{_select_upto_5.html.haml → _select_up_to_5.html.haml} +0 -0
  45. data/app/views/effective/polls_mailer/poll_reminder.liquid +13 -0
  46. data/app/views/effective/polls_mailer/poll_upcoming_reminder.liquid +11 -0
  47. data/app/views/effective/polls_mailer/poll_when_poll_ends.liquid +9 -0
  48. data/app/views/effective/polls_mailer/poll_when_poll_starts.liquid +13 -0
  49. data/config/effective_polls.rb +6 -1
  50. data/db/migrate/01_create_effective_polls.rb.erb +1 -0
  51. data/lib/effective_polls.rb +8 -3
  52. data/lib/effective_polls/version.rb +1 -1
  53. data/lib/generators/effective_polls/install_generator.rb +1 -1
  54. data/lib/generators/templates/effective_polls_mailer_preview.rb +17 -8
  55. data/lib/tasks/effective_polls_tasks.rake +5 -6
  56. metadata +25 -90
  57. data/app/views/admin/polls/_poll.html.haml +0 -2
  58. data/app/views/effective/polls/_form.html.haml +0 -10
  59. data/app/views/effective/polls/_poll.html.haml +0 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b49f5df5989ddd470b3090d2ac28ab5974e902bd33f8a57e05487025074cf0a8
4
- data.tar.gz: f3465afeb7bee7279348f24f7e85128d136cac9d47add5f3c67f8a1ee740062f
3
+ metadata.gz: aebcfa6f3efd89aa11a576d324f53b5d1438b94c8f71d2253c307898f600abef
4
+ data.tar.gz: c93f89535c8d5938d1025cf106f0a914b395e8b45c6992d48a02b9dd4a4465af
5
5
  SHA512:
6
- metadata.gz: 5ea3cf981517d7d8081feae614b054114f156826b5a694410d48f3418b7cf9df2db606c290d3f89a9ca1018ff4a8c64550528b9071436d7c7c02c863217467d1
7
- data.tar.gz: 76898e90f2e456e3ccbc4b24e022ce785b1375ff0afbc91cab27b31319c4bf40dab731900d77bced3788d9acb1cdceaec4b9d6483c984c0e8e0d4a20549f598c
6
+ metadata.gz: 787542d8c6ef91a83f68eded3aaf00455b36342e5e54a0572869d3d31588d307d2e2c0c96520560b77487227925b41927404b8622bf891bb422c89ca187c6ed7
7
+ data.tar.gz: 48a308bcaa45d2a478f918c5fa714aa870581a6ec572a5f08489550ce30740272ac1386668e0c3500b4567e789bc987790f46504a666700cc668ae7053e65059
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright 2020 Code and Effect Inc.
1
+ Copyright 2021 Code and Effect Inc.
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -2,21 +2,24 @@
2
2
 
3
3
  Online polls and user voting.
4
4
 
5
- An admin creates polls with one or more poll_questions. The poll can be assigned to users through a poll_ballot.
5
+ An admin creates polls with one or more poll_questions. The poll can be assigned to all users, individual users or selected users (a scope) and those users complete a 4-step wizard to submit a poll.
6
6
 
7
- The user can complete the poll_ballot and anonymously vote for each option.
7
+ All results are anonymized such that the user cannot be identified from the results.
8
8
 
9
- Some reports to display results.
9
+ Works with action_text for content bodies, and active_storage for file uploads.
10
10
 
11
11
  ## Getting Started
12
12
 
13
+ This requires Rails 6+ and Twitter Bootstrap 4 and just works with Devise.
14
+
13
15
  Please first install the [effective_datatables](https://github.com/code-and-effect/effective_datatables) gem.
14
16
 
15
- Please download and install [Twitter Bootstrap4](http://getbootstrap.com)
17
+ Please download and install the [Twitter Bootstrap4](http://getbootstrap.com)
16
18
 
17
19
  Add to your Gemfile:
18
20
 
19
21
  ```ruby
22
+ gem 'haml-rails' # or try using gem 'hamlit-rails'
20
23
  gem 'effective_polls'
21
24
  ```
22
25
 
@@ -34,7 +37,7 @@ rails generate effective_polls:install
34
37
 
35
38
  The generator will install an initializer which describes all configuration options and creates a database migration.
36
39
 
37
- If you want to tweak the table name (to use something other than the default 'polls'), manually adjust both the configuration file and the migration now.
40
+ If you want to tweak the table names, manually adjust both the configuration file and the migration now.
38
41
 
39
42
  Then migrate the database:
40
43
 
@@ -42,9 +45,50 @@ Then migrate the database:
42
45
  rake db:migrate
43
46
  ```
44
47
 
45
- ## Polls
48
+ Render the "available polls for current_user" datatable on your user dashboard:
49
+
50
+ ```haml
51
+ %h2 Polls
52
+ %p You may submit a ballot for the following polls.
53
+ = render_datatable(EffectivePollsDatatable.new, simple: true)
54
+ ```
55
+
56
+ Add a link to the admin menu:
57
+
58
+ ```haml
59
+ - if can? :admin, :effective_polls
60
+ = link_to 'Polls', effective_polls.admin_polls_path
61
+ ```
62
+
63
+ Set up your permissions:
64
+
65
+ ```ruby
66
+ # Regular signed up user. Guest users not supported.
67
+ if user.persisted?
68
+ can [:show, :update], Effective::Ballot, user_id: user.id
69
+ can :show, Effective::Poll
70
+ can :index, EffectivePollsDatatable
71
+ end
72
+
73
+ if user.admin?
74
+ can :admin, :effective_polls
46
75
 
47
- TODO
76
+ can :manage, Effective::Poll
77
+ can :manage, Effective::PollNotification
78
+ can :manage, Effective::PollQuestion
79
+ can :index, Admin::EffectivePollResultsDatatable
80
+ end
81
+ ```
82
+
83
+ And, if you want to use poll notifications, schedule the rake task to run every 10 minutes, or faster:
84
+
85
+ ```rake
86
+ rake effective_polls:notify
87
+ ```
88
+
89
+ ## Usage
90
+
91
+ You can render the results with `render('effective/poll_results/results', poll: poll)`.
48
92
 
49
93
  ## Authorization
50
94
 
@@ -97,19 +141,6 @@ rescue_from Effective::AccessDenied do |exception|
97
141
  end
98
142
  ```
99
143
 
100
- ### Permissions
101
-
102
- The permissions you actually want to define are as follows (using CanCan):
103
-
104
- ```ruby
105
- can [:index, :show], Effective::Poll
106
-
107
- if user.admin?
108
- can :manage, Effective::Poll
109
- can :admin, :effective_polls
110
- end
111
- ```
112
-
113
144
  ## License
114
145
 
115
146
  MIT License. Copyright [Code and Effect Inc.](http://www.codeandeffect.com/)
@@ -1,6 +1,6 @@
1
1
  module Admin
2
2
  class PollNotificationsController < ApplicationController
3
- layout (EffectivePolls.layout.kind_of?(Hash) ? EffectivePolls.layout[:admin] : EffectivePolls.layout)
3
+ layout EffectivePolls.layout[:admin]
4
4
 
5
5
  before_action(:authenticate_user!) if defined?(Devise)
6
6
  before_action { EffectivePolls.authorize!(self, :admin, :effective_polls) }
@@ -1,6 +1,6 @@
1
1
  module Admin
2
2
  class PollQuestionsController < ApplicationController
3
- layout (EffectivePolls.layout.kind_of?(Hash) ? EffectivePolls.layout[:admin] : EffectivePolls.layout)
3
+ layout EffectivePolls.layout[:admin]
4
4
 
5
5
  before_action(:authenticate_user!) if defined?(Devise)
6
6
  before_action { EffectivePolls.authorize!(self, :admin, :effective_polls) }
@@ -1,6 +1,6 @@
1
1
  module Admin
2
2
  class PollsController < ApplicationController
3
- layout (EffectivePolls.layout.kind_of?(Hash) ? EffectivePolls.layout[:admin] : EffectivePolls.layout)
3
+ layout EffectivePolls.layout[:admin]
4
4
 
5
5
  before_action(:authenticate_user!) if defined?(Devise)
6
6
  before_action { EffectivePolls.authorize!(self, :admin, :effective_polls) }
@@ -1,6 +1,6 @@
1
1
  module Effective
2
2
  class BallotsController < ApplicationController
3
- layout (EffectivePolls.layout.kind_of?(Hash) ? EffectivePolls.layout[:polls] : EffectivePolls.layout)
3
+ layout EffectivePolls.layout[:polls]
4
4
 
5
5
  before_action(:authenticate_user!) if defined?(Devise)
6
6
  include Effective::WizardController
@@ -1,15 +1,15 @@
1
1
  class Admin::EffectivePollsDatatable < Effective::Datatable
2
2
  filters do
3
+ scope :all
3
4
  scope :upcoming
4
5
  scope :available
5
6
  scope :completed
6
- scope :all
7
7
  end
8
8
 
9
9
  datatable do
10
10
  order :start_at, :desc
11
11
 
12
- col :id, visible: false
12
+ col :token, visible: false
13
13
  col :created_at, visible: false
14
14
  col :updated_at, visible: false
15
15
 
@@ -1,22 +1,70 @@
1
1
  module Effective
2
- class PollsMailer < ActionMailer::Base
3
- default from: EffectivePolls.mailer[:default_from]
2
+ class PollsMailer < EffectivePolls.mailer_class
4
3
  layout EffectivePolls.mailer[:layout].presence || 'effective_polls_mailer_layout'
5
4
 
6
- def poll_upcoming_reminder(poll_notification, bcc)
7
- mail(bcc: bcc, body: poll_notification.body, subject: poll_notification.subject)
5
+ def poll_upcoming_reminder(poll_notification, user)
6
+ @assigns = effective_email_templates_assigns(poll_notification, user)
7
+
8
+ mail(
9
+ to: user.email,
10
+ from: poll_notification.from,
11
+ body: poll_notification.body,
12
+ subject: poll_notification.subject
13
+ )
8
14
  end
9
15
 
10
- def poll_start(poll_notification, bcc)
11
- mail(bcc: bcc, body: poll_notification.body, subject: poll_notification.subject)
16
+ def poll_when_poll_starts(poll_notification, user)
17
+ @assigns = effective_email_templates_assigns(poll_notification, user)
18
+
19
+ mail(
20
+ to: user.email,
21
+ from: poll_notification.from,
22
+ body: poll_notification.body,
23
+ subject: poll_notification.subject
24
+ )
12
25
  end
13
26
 
14
- def poll_reminder(poll_notification, bcc)
15
- mail(bcc: bcc, body: poll_notification.body, subject: poll_notification.subject)
27
+ def poll_reminder(poll_notification, user)
28
+ @assigns = effective_email_templates_assigns(poll_notification, user)
29
+
30
+ mail(
31
+ to: user.email,
32
+ from: poll_notification.from,
33
+ body: poll_notification.body,
34
+ subject: poll_notification.subject
35
+ )
16
36
  end
17
37
 
18
- def poll_end(poll_notification, bcc)
19
- mail(bcc: bcc, body: poll_notification.body, subject: poll_notification.subject)
38
+ def poll_when_poll_ends(poll_notification, user)
39
+ @assigns = effective_email_templates_assigns(poll_notification, user)
40
+
41
+ mail(
42
+ to: user.email,
43
+ from: poll_notification.from,
44
+ body: poll_notification.body,
45
+ subject: poll_notification.subject
46
+ )
47
+ end
48
+
49
+ private
50
+
51
+ # Only relevant if the effective_email_templates gem is present
52
+ def effective_email_templates_assigns(poll_notification, user)
53
+ raise('expected an Effective::PollNotification') unless poll_notification.kind_of?(Effective::PollNotification)
54
+ raise('expected a User') unless user.kind_of?(User)
55
+
56
+ poll = poll_notification.poll
57
+ raise('expected poll to be persisted') unless poll&.persisted?
58
+
59
+ {
60
+ available_date: poll.available_date,
61
+ title: poll.title,
62
+ url: effective_polls.new_poll_ballot_url(poll),
63
+ user: {
64
+ name: user.to_s,
65
+ email: user.email
66
+ }
67
+ }
20
68
  end
21
69
 
22
70
  end
@@ -48,19 +48,19 @@ module Effective
48
48
  validates :poll_question_option_ids, if: -> { poll_question&.choose_one? },
49
49
  length: { maximum: 1, message: 'please choose 1 option only' }
50
50
 
51
- validates :poll_question_option_ids, if: -> { poll_question&.select_upto_1? },
51
+ validates :poll_question_option_ids, if: -> { poll_question&.select_up_to_1? },
52
52
  length: { maximum: 1, message: 'please select 1 option or fewer' }
53
53
 
54
- validates :poll_question_option_ids, if: -> { poll_question&.select_upto_2? },
54
+ validates :poll_question_option_ids, if: -> { poll_question&.select_up_to_2? },
55
55
  length: { maximum: 2, message: 'please select 2 options or fewer' }
56
56
 
57
- validates :poll_question_option_ids, if: -> { poll_question&.select_upto_3? },
57
+ validates :poll_question_option_ids, if: -> { poll_question&.select_up_to_3? },
58
58
  length: { maximum: 3, message: 'please select 3 options or fewer' }
59
59
 
60
- validates :poll_question_option_ids, if: -> { poll_question&.select_upto_4? },
60
+ validates :poll_question_option_ids, if: -> { poll_question&.select_up_to_4? },
61
61
  length: { maximum: 4, message: 'please select 4 options or fewer' }
62
62
 
63
- validates :poll_question_option_ids, if: -> { poll_question&.select_upto_5? },
63
+ validates :poll_question_option_ids, if: -> { poll_question&.select_up_to_5? },
64
64
  length: { maximum: 5, message: 'please select 5 options or fewer' }
65
65
 
66
66
  def to_s
@@ -78,7 +78,7 @@ module Effective
78
78
  return upload_file if poll_question.upload_file?
79
79
 
80
80
  return poll_question_options.first if poll_question.choose_one?
81
- return poll_question_options.first if poll_question.select_upto_1?
81
+ return poll_question_options.first if poll_question.select_up_to_1?
82
82
  return poll_question_options if poll_question.poll_question_option?
83
83
 
84
84
  raise('unknown response for unexpected poll question category')
@@ -1,7 +1,5 @@
1
1
  module Effective
2
2
  class Poll < ActiveRecord::Base
3
- attr_accessor :skip_started_validation
4
-
5
3
  has_rich_text :all_steps_content
6
4
  has_rich_text :start_content
7
5
  has_rich_text :vote_content
@@ -23,6 +21,10 @@ module Effective
23
21
 
24
22
  acts_as_tokened
25
23
 
24
+ if respond_to?(:log_changes)
25
+ log_changes(except: [:ballots, :ballot_responses, :completed_ballots, :completed_ballot_responses])
26
+ end
27
+
26
28
  AUDIENCES = ['All Users', 'Individual Users', 'Selected Users']
27
29
 
28
30
  effective_resource do
@@ -57,7 +59,6 @@ module Effective
57
59
  }
58
60
 
59
61
  scope :sorted, -> { order(:start_at) }
60
- scope :editable, -> { upcoming }
61
62
 
62
63
  scope :upcoming, -> { where('start_at > ?', Time.zone.now) }
63
64
  scope :available, -> { where('start_at <= ? AND (end_at > ? OR end_at IS NULL)', Time.zone.now, Time.zone.now) }
@@ -69,14 +70,6 @@ module Effective
69
70
  validates :audience, inclusion: { in: AUDIENCES }
70
71
  validates :audience_scope, presence: true, unless: -> { audience == 'All Users' }
71
72
 
72
- validate(if: -> { started? }, unless: -> { skip_started_validation }) do
73
- self.errors.add(:base, 'has already started. a poll cannot be changed after it has started.')
74
- end
75
-
76
- validate(if: -> { start_at.present? && !started? }, unless: -> { skip_started_validation }) do
77
- self.errors.add(:start_at, 'must be a future date') if start_at < Time.zone.now
78
- end
79
-
80
73
  validate(if: -> { start_at.present? && end_at.present? }) do
81
74
  self.errors.add(:end_at, 'must be after the start date') unless end_at > start_at
82
75
  end
@@ -90,8 +83,8 @@ module Effective
90
83
  available? && users.include?(user)
91
84
  end
92
85
 
93
- def users
94
- case audience
86
+ def users(except_completed: false)
87
+ users = case audience
95
88
  when 'All Users'
96
89
  User.all
97
90
  when 'Individual Users'
@@ -103,13 +96,11 @@ module Effective
103
96
  else
104
97
  raise('unexpected audience')
105
98
  end
106
- end
107
99
 
108
- def emails(exclude_completed: false)
109
- if exclude_completed
110
- users.where.not(id: completed_ballots.select('user_id as id')).pluck(:email)
100
+ if except_completed
101
+ users.where.not(id: completed_ballots.select('user_id as id'))
111
102
  else
112
- users.pluck(:email)
103
+ users
113
104
  end
114
105
  end
115
106
 
@@ -1,9 +1,10 @@
1
1
  module Effective
2
2
  class PollNotification < ActiveRecord::Base
3
3
  belongs_to :poll
4
+ log_changes(to: :poll) if respond_to?(:log_changes)
4
5
 
5
- BATCHSIZE = (Rails.env.test? ? 3 : 250)
6
6
  CATEGORIES = ['Upcoming reminder', 'When poll starts', 'Reminder', 'When poll ends']
7
+ EMAIL_TEMPLATE_VARIABLES = ['available_date', 'title', 'url', 'user.name', 'user.email']
7
8
 
8
9
  UPCOMING_REMINDERS = {
9
10
  '1 hour before' => 1.hours.to_i,
@@ -44,6 +45,7 @@ module Effective
44
45
  reminder :integer # Number of seconds before poll.start_at
45
46
 
46
47
  # Email
48
+ from :string
47
49
  subject :string
48
50
  body :text
49
51
 
@@ -65,9 +67,16 @@ module Effective
65
67
 
66
68
  validates :poll, presence: true
67
69
  validates :category, presence: true, inclusion: { in: CATEGORIES }
70
+
71
+ validates :from, presence: true
68
72
  validates :subject, presence: true
69
73
  validates :body, presence: true
70
74
 
75
+ if EffectivePolls.use_effective_email_templates
76
+ validates :body, liquid: true
77
+ validates :subject, liquid: true
78
+ end
79
+
71
80
  validates :reminder, if: -> { reminder? || upcoming_reminder? },
72
81
  presence: true, uniqueness: { scope: [:poll_id, :category], message: 'already exists' }
73
82
 
@@ -75,6 +84,10 @@ module Effective
75
84
  'poll notification'
76
85
  end
77
86
 
87
+ def email_template
88
+ 'poll_' + category.to_s.parameterize.underscore
89
+ end
90
+
78
91
  def upcoming_reminder?
79
92
  category == 'Upcoming reminder'
80
93
  end
@@ -115,26 +128,13 @@ module Effective
115
128
  def notify!
116
129
  return false unless notify_now?
117
130
 
118
- # We send to all email addresses, except for the 'Reminder' that exclude completed users
119
- emails = poll.emails(exclude_completed: (category == 'Reminder'))
131
+ # We send to all users, except for the 'Reminder' that exclude completed users
132
+ users = poll.users(except_completed: (category == 'Reminder'))
120
133
 
121
134
  update_column(:started_at, Time.zone.now)
122
135
 
123
- emails.in_groups_of(BATCHSIZE, false).each do |emails|
124
- mail = case category
125
- when 'When poll starts'
126
- Effective::PollsMailer.poll_start(self, emails)
127
- when 'When poll ends'
128
- Effective::PollsMailer.poll_end(self, emails)
129
- when 'Upcoming reminder'
130
- Effective::PollsMailer.poll_upcoming_reminder(self, emails)
131
- when 'Reminder'
132
- Effective::PollsMailer.poll_reminder(self, emails)
133
- else
134
- raise('unexpected category')
135
- end
136
-
137
- mail.deliver_now
136
+ users.find_each do |user|
137
+ Effective::PollsMailer.public_send(email_template, self, user).deliver_now
138
138
  end
139
139
 
140
140
  update_column(:completed_at, Time.zone.now)
@@ -6,15 +6,16 @@ module Effective
6
6
  accepts_nested_attributes_for :poll_question_options, reject_if: :all_blank, allow_destroy: true
7
7
 
8
8
  has_rich_text :body
9
+ log_changes(to: :poll) if respond_to?(:log_changes)
9
10
 
10
11
  CATEGORIES = [
11
12
  'Choose one', # Radios
12
13
  'Select all that apply', # Checks
13
- 'Select upto 1',
14
- 'Select upto 2',
15
- 'Select upto 3',
16
- 'Select upto 4',
17
- 'Select upto 5',
14
+ 'Select up to 1',
15
+ 'Select up to 2',
16
+ 'Select up to 3',
17
+ 'Select up to 4',
18
+ 'Select up to 5',
18
19
  'Date', # Date Field
19
20
  'Email', # Email Field
20
21
  'Number', # Numeric Field
@@ -26,11 +27,11 @@ module Effective
26
27
  WITH_OPTIONS_CATEGORIES = [
27
28
  'Choose one', # Radios
28
29
  'Select all that apply', # Checks
29
- 'Select upto 1',
30
- 'Select upto 2',
31
- 'Select upto 3',
32
- 'Select upto 4',
33
- 'Select upto 5'
30
+ 'Select up to 1',
31
+ 'Select up to 2',
32
+ 'Select up to 3',
33
+ 'Select up to 4',
34
+ 'Select up to 5'
34
35
  ]
35
36
 
36
37
  effective_resource do
@@ -2,54 +2,41 @@
2
2
  - if inline_datatable?
3
3
  = f.hidden_field :poll_id
4
4
  - else
5
- = f.select :poll_id, Effective::Poll.sorted.editable.all
5
+ = f.select :poll_id, Effective::Poll.sorted.all
6
6
 
7
7
  = f.select :category, Effective::PollNotification::CATEGORIES,
8
8
  label: 'Send an email notification'
9
9
 
10
- = f.show_if :category, 'Upcoming reminder' do
10
+ - # Render email templates
11
+ - Effective::PollNotification::CATEGORIES.each do |category|
12
+ - template = 'poll_' + category.parameterize.underscore
11
13
 
12
- = f.select :reminder, Effective::PollNotification::UPCOMING_REMINDERS, label: false,
13
- hint: "before the poll starts on #{f.object.poll&.start_at&.strftime('%F')}."
14
+ = f.show_if :category, category do
15
+ = render "/admin/poll_notifications/form_#{template}", f: f
14
16
 
15
- .alert.alert-warning
16
- %strong Upcoming Reminders
17
- are sent to the entire audience before the poll starts.
18
- %br
19
- Use upcoming reminders to advertise, prepare, or communicate to your audience before the poll begins.
17
+ - if f.object.category == category
18
+ = f.email_field :from
19
+ = f.text_field :subject
20
+ = f.text_area :body, rows: 10
20
21
 
21
- = f.show_if :category, 'When poll starts' do
22
- .alert.alert-warning
23
- %strong When poll starts
24
- notifications will be sent within 10 minutes of the poll start time.
22
+ - elsif EffectivePolls.use_effective_email_templates == false
23
+ = f.email_field :from, value: EffectivePolls.mailer[:default_from]
24
+ = f.text_field :subject, value: ''
25
+ = f.text_area :body, rows: 10, value: ''
25
26
 
26
- = f.show_if :category, 'Reminder' do
27
+ - else
28
+ - email_template = Effective::EmailTemplate.where(template_name: template).first!
27
29
 
28
- = f.select :reminder, Effective::PollNotification::REMINDERS, label: false,
29
- hint: "after the poll starts on #{f.object.poll&.start_at&.strftime('%F')}."
30
+ = f.email_field :from, value: email_template.from
31
+ = f.text_field :subject, value: email_template.subject
32
+ = f.text_area :body, rows: 10, value: email_template.body
30
33
 
31
- .alert.alert-warning
32
- %strong Reminders
33
- are sent to users in the audience who have not yet completed their ballot.
34
- %br
35
- Use reminders to boost your audience participation and remind people to vote.
34
+ %p The available variables are:
36
35
 
37
- = f.show_if :category, 'When poll ends' do
38
- .alert.alert-warning
39
- %strong When poll ends
40
- notifications will be sent within 10 minutes of the poll end time.
36
+ %ul
37
+ - Effective::PollNotification::EMAIL_TEMPLATE_VARIABLES.each do |variable|
38
+ %li {{ #{variable} }}
41
39
 
42
- = f.text_field :subject, label: 'Email Subject'
43
- = f.text_area :body, label: 'Email Body'
44
-
45
- .alert.alert-warning
46
- Email content must not contain any personal details.
47
- %br
48
- This content will be sent in a mass email with hundreds of bcc'd recipients.
49
-
50
- - if poll_notification.poll.present?
51
- %br
52
- The url for this poll will be:
53
- = effective_polls.poll_url(poll_notification.poll)
40
+ %small.text-muted Only a developer can add additional variables
54
41
 
55
42
  = effective_submit(f)
@@ -0,0 +1,8 @@
1
+ = f.select :reminder, Effective::PollNotification::REMINDERS, label: false,
2
+ hint: "after the poll starts on #{f.object.poll&.start_at&.strftime('%F')}."
3
+
4
+ .alert.alert-warning
5
+ %strong Reminders
6
+ are sent to users in the audience who have not yet completed their ballot.
7
+ %br
8
+ Use reminders to boost your audience participation and remind people to vote.
@@ -0,0 +1,8 @@
1
+ = f.select :reminder, Effective::PollNotification::UPCOMING_REMINDERS, label: false,
2
+ hint: "before the poll starts on #{f.object.poll&.start_at&.strftime('%F')}."
3
+
4
+ .alert.alert-warning
5
+ %strong Upcoming Reminders
6
+ are sent to the entire audience before the poll starts.
7
+ %br
8
+ Use upcoming reminders to advertise, prepare, or communicate to your audience before the poll begins.
@@ -0,0 +1,3 @@
1
+ .alert.alert-warning
2
+ %strong When poll ends
3
+ notifications will be sent within 10 minutes of the poll end time.
@@ -0,0 +1,3 @@
1
+ .alert.alert-warning
2
+ %strong When poll starts
3
+ notifications will be sent within 10 minutes of the poll start time.
@@ -22,35 +22,35 @@
22
22
  %h5 Select all that apply
23
23
  %p Display checkboxes to select all options that apply
24
24
 
25
- = f.show_if :category, 'Select upto 1' do
25
+ = f.show_if :category, 'Select up to 1' do
26
26
  .card
27
27
  .card-body
28
- %h5 Select upto 1 (one)
29
- %p Display checkboxes to select upto 1 option
28
+ %h5 Select up to 1 (one)
29
+ %p Display checkboxes to select up to 1 option
30
30
 
31
- = f.show_if :category, 'Select upto 2' do
31
+ = f.show_if :category, 'Select up to 2' do
32
32
  .card
33
33
  .card-body
34
- %h5 Select upto 2 (two)
35
- %p Display checkboxes to select upto 2 options
34
+ %h5 Select up to 2 (two)
35
+ %p Display checkboxes to select up to 2 options
36
36
 
37
- = f.show_if :category, 'Select upto 3' do
37
+ = f.show_if :category, 'Select up to 3' do
38
38
  .card
39
39
  .card-body
40
- %h5 Select upto 3 (three)
41
- %p Display checkboxes to select upto 3 options
40
+ %h5 Select up to 3 (three)
41
+ %p Display checkboxes to select up to 3 options
42
42
 
43
- = f.show_if :category, 'Select upto 4' do
43
+ = f.show_if :category, 'Select up to 4' do
44
44
  .card
45
45
  .card-body
46
- %h5 Select upto 4 (four)
47
- %p Display checkboxes to select upto 4 options
46
+ %h5 Select up to 4 (four)
47
+ %p Display checkboxes to select up to 4 options
48
48
 
49
- = f.show_if :category, 'Select upto 5' do
49
+ = f.show_if :category, 'Select up to 5' do
50
50
  .card
51
51
  .card-body
52
- %h5 Select upto 5 (five)
53
- %p Display checkboxes to select upto 5 options
52
+ %h5 Select up to 5 (five)
53
+ %p Display checkboxes to select up to 5 options
54
54
 
55
55
  = f.show_if :category, 'Short Answer' do
56
56
  .card
@@ -12,9 +12,13 @@
12
12
 
13
13
  = tab 'Notifications' do
14
14
  %p
15
- The following email notification will be sent to all
15
+ The following email notifications will be sent to
16
16
  = pluralize(poll.users.count, 'users')
17
17
  in the audience.
18
18
 
19
19
  - datatable = Admin::EffectivePollNotificationsDatatable.new(poll_id: poll.id)
20
20
  = render_datatable(datatable, inline: true, simple: true)
21
+
22
+ - if poll.respond_to?(:log_changes_datatable)
23
+ = tab 'Logs' do
24
+ = render_datatable(poll.log_changes_datatable)
@@ -1,7 +1,7 @@
1
1
  = effective_form_with(model: [:admin, poll], engine: true) do |f|
2
- = f.text_field :title, hint: 'The title of your poll.'
2
+ = f.text_field :title, hint: 'The title of your poll or election.'
3
3
 
4
- = f.datetime_field :start_at, input_js: { minDate: [f.object.start_at.presence, Time.zone.now].compact.min.strftime('%F') }
4
+ = f.datetime_field :start_at, input_js: { minDate: Time.zone.now.beginning_of_day.strftime('%F') }
5
5
  = f.datetime_field :end_at
6
6
 
7
7
  -# Audience
@@ -1 +1,2 @@
1
- = f.date_field :date, label: false, required: poll_question.required?
1
+ .row
2
+ .col-sm-6= f.date_field :date, label: false, required: poll_question.required?
@@ -1 +1,2 @@
1
- = f.email_field :email, label: false, required: poll_question.required?
1
+ .row
2
+ .col-sm-6= f.email_field :email, label: false, required: poll_question.required?
@@ -1 +1,2 @@
1
- = f.number_field :number, label: false, required: poll_question.required?
1
+ .row
2
+ .col-sm-6= f.number_field :number, label: false, required: poll_question.required?
@@ -2,8 +2,8 @@
2
2
  %table.table.table-hover
3
3
  %thead
4
4
  %tr
5
- %th Poll Question
6
- %th Ballot Response
5
+ %th Question
6
+ %th Response
7
7
 
8
8
  %tbody
9
9
  - ballot.poll.poll_questions.each_with_index do |poll_question, index|
@@ -1,5 +1,5 @@
1
1
  = render_wizard_sidebar(resource) do
2
- %h1 Poll: #{resource.poll}
2
+ %h1= resource.poll
3
3
 
4
4
  .alert.alert-warning
5
5
  This is a <strong>Secret Ballot</strong>.
@@ -1,5 +1,5 @@
1
1
  = render_wizard_sidebar(resource) do
2
- %h1 Review: #{resource.poll}
2
+ %h1= resource.poll
3
3
 
4
4
  - if resource.poll.all_steps_content.present?
5
5
  .mb-2= resource.poll.all_steps_content
@@ -1,5 +1,5 @@
1
1
  = render_wizard_sidebar(resource) do
2
- %h1 Ballot: #{resource.poll}
2
+ %h1= resource.poll
3
3
 
4
4
  - if resource.poll.all_steps_content.present?
5
5
  .mb-2= resource.poll.all_steps_content
@@ -20,7 +20,7 @@
20
20
  %table.table.table-hover
21
21
  %thead
22
22
  %tr
23
- %th Poll Question
23
+ %th Question
24
24
  %th Results
25
25
 
26
26
  %tbody
@@ -0,0 +1,13 @@
1
+ ---
2
+ subject: 'Reminder - Please submit your ballot for {{ title }}'
3
+ from: 'admin@example.com'
4
+ ---
5
+ Hello {{ user.name }},
6
+
7
+ The {{ title }} poll has already started.
8
+
9
+ Please remember to submit your ballot.
10
+
11
+ {{ url }}
12
+
13
+ Thank you
@@ -0,0 +1,11 @@
1
+ ---
2
+ subject: '{{ title }} is upcoming'
3
+ from: 'admin@example.com'
4
+ ---
5
+ Hello {{ user.name }},
6
+
7
+ The {{ title }} poll is upcoming.
8
+
9
+ It will be available {{ available_date }}.
10
+
11
+ Thank you
@@ -0,0 +1,9 @@
1
+ ---
2
+ subject: '{{ title }} has ended'
3
+ from: 'admin@example.com'
4
+ ---
5
+ Hello {{ user.name }},
6
+
7
+ The {{ title }} poll has ended.
8
+
9
+ Thank you
@@ -0,0 +1,13 @@
1
+ ---
2
+ subject: '{{ title }} has started'
3
+ from: 'admin@example.com'
4
+ ---
5
+ Hello {{ user.name }},
6
+
7
+ The {{ title }} poll has started.
8
+
9
+ Please click below to submit your ballot.
10
+
11
+ {{ url }}
12
+
13
+ Thank you
@@ -53,7 +53,12 @@ EffectivePolls.setup do |config|
53
53
  #
54
54
  config.mailer = {
55
55
  layout: 'effective_polls_mailer_layout',
56
- default_from: 'info@example.com'
56
+ default_from: 'no-reply@example.com'
57
57
  }
58
58
 
59
+ # Will work with effective_email_templates gem:
60
+ # - The poll notifications email content will be preopulated based off the template
61
+ # - Uses a EmailTemplatesMailer mailer instead of ActionMailer::Base
62
+ config.use_effective_email_templates = false
63
+
59
64
  end
@@ -20,6 +20,7 @@ class CreateEffectivePolls < ActiveRecord::Migration[6.0]
20
20
  t.string :category
21
21
  t.integer :reminder
22
22
 
23
+ t.string :from
23
24
  t.string :subject
24
25
  t.text :body
25
26
 
@@ -13,13 +13,13 @@ module EffectivePolls
13
13
  mattr_accessor :ballot_response_options_table_name
14
14
 
15
15
  mattr_accessor :authorization_method
16
- mattr_accessor :permitted_params
17
16
 
18
17
  mattr_accessor :layout
19
18
 
20
19
  mattr_accessor :audience_user_scopes
21
20
 
22
21
  # Hashes of configs
22
+ mattr_accessor :use_effective_email_templates
23
23
  mattr_accessor :mailer
24
24
 
25
25
  def self.setup
@@ -43,8 +43,13 @@ module EffectivePolls
43
43
  raise Effective::AccessDenied.new('Access Denied', action, resource) unless authorized?(controller, action, resource)
44
44
  end
45
45
 
46
- def self.permitted_params
47
- raise('todo')
46
+ def self.mailer_class
47
+ if use_effective_email_templates
48
+ require 'effective_email_templates'
49
+ Effective::EmailTemplatesMailer
50
+ else
51
+ ActionMailer::Base
52
+ end
48
53
  end
49
54
 
50
55
  end
@@ -1,3 +1,3 @@
1
1
  module EffectivePolls
2
- VERSION = '0.0.1'
2
+ VERSION = '0.1.3'
3
3
  end
@@ -26,7 +26,7 @@ module EffectivePolls
26
26
  @poll_question_options_table_name = ':' + EffectivePolls.poll_question_options_table_name.to_s
27
27
  @ballots_table_name = ':' + EffectivePolls.ballots_table_name.to_s
28
28
  @ballot_responses_table_name = ':' + EffectivePolls.ballot_responses_table_name.to_s
29
- @ballot_response_options_table_name = ':' + EffectivePolls.ballot_responses_table_name.to_s
29
+ @ballot_response_options_table_name = ':' + EffectivePolls.ballot_response_options_table_name.to_s
30
30
 
31
31
  migration_template ('../' * 3) + 'db/migrate/01_create_effective_polls.rb.erb', 'db/migrate/create_effective_polls.rb'
32
32
  end
@@ -2,29 +2,38 @@
2
2
 
3
3
  class EffectivePollsMailerPreview < ActionMailer::Preview
4
4
 
5
- def poll_upcoming_reminder(poll_notification, bcc)
6
- mail(bcc: bcc, body: poll_notification.body, subject: poll_notification.subject)
5
+ def poll_upcoming_reminder
6
+ poll_notification = build_poll_notification('The poll will start soon')
7
+ Effective::PollsMailer.poll_upcoming_reminder(poll_notification, build_user)
7
8
  end
8
9
 
9
10
  def poll_start
10
11
  poll_notification = build_poll_notification('The poll has started')
11
- Effective::PollsMailer.poll_start(poll_notification, bccs)
12
+ Effective::PollsMailer.poll_start(poll_notification, build_user)
12
13
  end
13
14
 
14
15
  def poll_reminder
15
- poll_notification = build_poll_notification('This is a reminder')
16
- Effective::PollsMailer.poll_reminder(poll_notification, bccs)
16
+ poll_notification = build_poll_notification('The poll started already and you have not participated')
17
+ Effective::PollsMailer.poll_reminder(poll_notification, build_user)
17
18
  end
18
19
 
19
20
  def poll_end
20
21
  poll_notification = build_poll_notification('The poll has ended')
21
- Effective::PollsMailer.poll_end(poll_notification, bccs)
22
+ Effective::PollsMailer.poll_end(poll_notification, build_user)
22
23
  end
23
24
 
24
25
  protected
25
26
 
26
- def bccs
27
- ['one@example.com', 'two@example.com', 'three@example.com', 'two-hundred-fifty@example.com']
27
+ def build_user
28
+ User.new(email: 'buyer@website.com').tap do |user|
29
+ user.name = 'Valued Customer' if user.respond_to?(:name=)
30
+ user.full_name = 'Valued Customer' if user.respond_to?(:full_name=)
31
+
32
+ if user.respond_to?(:first_name=) && user.respond_to?(:last_name=)
33
+ user.first_name = 'Valued'
34
+ user.last_name = 'Customer'
35
+ end
36
+ end
28
37
  end
29
38
 
30
39
  def build_poll_notification(text)
@@ -5,17 +5,16 @@ namespace :effective_polls do
5
5
  task notify: :environment do
6
6
  poll_notifications = Effective::PollNotification.all.deep.notifiable
7
7
 
8
- poll_notifications.find_each do |poll_notification|
8
+ poll_notifications.find_each do |notification|
9
9
  begin
10
- notified = poll_notification.notify!
11
- puts "Sent #{poll_notification.category} for #{poll_notification.poll}" if notified
10
+ notified = notification.notify!
11
+ puts "Sent #{notification.category} for #{notification.poll}" if notified
12
12
  rescue => e
13
13
  if defined?(ExceptionNotifier)
14
- data = { poll_notification_id: poll_notification.id, poll_id: poll_notification.poll_id }
15
- ExceptionNotifier.notify_exception(e, data: data)
14
+ ExceptionNotifier.notify_exception(e, data: { poll_notification_id: notification.id, poll_id: notification.poll_id })
16
15
  end
17
16
 
18
- puts "Error with effective poll_notification #{poll_notification.id}: #{e.errors.inspect}"
17
+ puts "Error with effective poll_notification #{notification.id}: #{e.errors.inspect}"
19
18
  end
20
19
  end
21
20
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: effective_polls
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Code and Effect
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-01-19 00:00:00.000000000 Z
11
+ date: 2021-02-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -80,76 +80,6 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
- - !ruby/object:Gem::Dependency
84
- name: sqlite3
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: '0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - ">="
95
- - !ruby/object:Gem::Version
96
- version: '0'
97
- - !ruby/object:Gem::Dependency
98
- name: devise
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- version: '0'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - ">="
109
- - !ruby/object:Gem::Version
110
- version: '0'
111
- - !ruby/object:Gem::Dependency
112
- name: haml-rails
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - ">="
116
- - !ruby/object:Gem::Version
117
- version: '0'
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - ">="
123
- - !ruby/object:Gem::Version
124
- version: '0'
125
- - !ruby/object:Gem::Dependency
126
- name: wicked
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - ">="
130
- - !ruby/object:Gem::Version
131
- version: '0'
132
- type: :development
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - ">="
137
- - !ruby/object:Gem::Version
138
- version: '0'
139
- - !ruby/object:Gem::Dependency
140
- name: pry-byebug
141
- requirement: !ruby/object:Gem::Requirement
142
- requirements:
143
- - - ">="
144
- - !ruby/object:Gem::Version
145
- version: '0'
146
- type: :development
147
- prerelease: false
148
- version_requirements: !ruby/object:Gem::Requirement
149
- requirements:
150
- - - ">="
151
- - !ruby/object:Gem::Version
152
- version: '0'
153
83
  description: Online polls and user voting.
154
84
  email:
155
85
  - info@codeandeffect.com
@@ -183,11 +113,14 @@ files:
183
113
  - app/models/effective/poll_question.rb
184
114
  - app/models/effective/poll_question_option.rb
185
115
  - app/views/admin/poll_notifications/_form.html.haml
116
+ - app/views/admin/poll_notifications/_form_poll_reminder.html.haml
117
+ - app/views/admin/poll_notifications/_form_poll_upcoming_reminder.html.haml
118
+ - app/views/admin/poll_notifications/_form_poll_when_poll_ends.html.haml
119
+ - app/views/admin/poll_notifications/_form_poll_when_poll_starts.html.haml
186
120
  - app/views/admin/poll_questions/_form.html.haml
187
121
  - app/views/admin/polls/_form.html.haml
188
122
  - app/views/admin/polls/_form_content.html.haml
189
123
  - app/views/admin/polls/_form_poll.html.haml
190
- - app/views/admin/polls/_poll.html.haml
191
124
  - app/views/admin/polls/results.html.haml
192
125
  - app/views/effective/ballot_responses/_ballot_response.html.haml
193
126
  - app/views/effective/ballot_responses/_fields.html.haml
@@ -197,11 +130,11 @@ files:
197
130
  - app/views/effective/ballot_responses/fields/_long_answer.html.haml
198
131
  - app/views/effective/ballot_responses/fields/_number.html.haml
199
132
  - app/views/effective/ballot_responses/fields/_select_all_that_apply.html.haml
200
- - app/views/effective/ballot_responses/fields/_select_upto_1.html.haml
201
- - app/views/effective/ballot_responses/fields/_select_upto_2.html.haml
202
- - app/views/effective/ballot_responses/fields/_select_upto_3.html.haml
203
- - app/views/effective/ballot_responses/fields/_select_upto_4.html.haml
204
- - app/views/effective/ballot_responses/fields/_select_upto_5.html.haml
133
+ - app/views/effective/ballot_responses/fields/_select_up_to_1.html.haml
134
+ - app/views/effective/ballot_responses/fields/_select_up_to_2.html.haml
135
+ - app/views/effective/ballot_responses/fields/_select_up_to_3.html.haml
136
+ - app/views/effective/ballot_responses/fields/_select_up_to_4.html.haml
137
+ - app/views/effective/ballot_responses/fields/_select_up_to_5.html.haml
205
138
  - app/views/effective/ballot_responses/fields/_short_answer.html.haml
206
139
  - app/views/effective/ballot_responses/fields/_upload_file.html.haml
207
140
  - app/views/effective/ballot_responses/responses/_choose_one.html.haml
@@ -210,11 +143,11 @@ files:
210
143
  - app/views/effective/ballot_responses/responses/_long_answer.html.haml
211
144
  - app/views/effective/ballot_responses/responses/_number.html.haml
212
145
  - app/views/effective/ballot_responses/responses/_select_all_that_apply.html.haml
213
- - app/views/effective/ballot_responses/responses/_select_upto_1.html.haml
214
- - app/views/effective/ballot_responses/responses/_select_upto_2.html.haml
215
- - app/views/effective/ballot_responses/responses/_select_upto_3.html.haml
216
- - app/views/effective/ballot_responses/responses/_select_upto_4.html.haml
217
- - app/views/effective/ballot_responses/responses/_select_upto_5.html.haml
146
+ - app/views/effective/ballot_responses/responses/_select_up_to_1.html.haml
147
+ - app/views/effective/ballot_responses/responses/_select_up_to_2.html.haml
148
+ - app/views/effective/ballot_responses/responses/_select_up_to_3.html.haml
149
+ - app/views/effective/ballot_responses/responses/_select_up_to_4.html.haml
150
+ - app/views/effective/ballot_responses/responses/_select_up_to_5.html.haml
218
151
  - app/views/effective/ballot_responses/responses/_short_answer.html.haml
219
152
  - app/views/effective/ballot_responses/responses/_upload_file.html.haml
220
153
  - app/views/effective/ballots/_ballot.html.haml
@@ -231,15 +164,17 @@ files:
231
164
  - app/views/effective/poll_results/results/_number.html.haml
232
165
  - app/views/effective/poll_results/results/_poll_question_option.html.haml
233
166
  - app/views/effective/poll_results/results/_select_all_that_apply.html.haml
234
- - app/views/effective/poll_results/results/_select_upto_1.html.haml
235
- - app/views/effective/poll_results/results/_select_upto_2.html.haml
236
- - app/views/effective/poll_results/results/_select_upto_3.html.haml
237
- - app/views/effective/poll_results/results/_select_upto_4.html.haml
238
- - app/views/effective/poll_results/results/_select_upto_5.html.haml
167
+ - app/views/effective/poll_results/results/_select_up_to_1.html.haml
168
+ - app/views/effective/poll_results/results/_select_up_to_2.html.haml
169
+ - app/views/effective/poll_results/results/_select_up_to_3.html.haml
170
+ - app/views/effective/poll_results/results/_select_up_to_4.html.haml
171
+ - app/views/effective/poll_results/results/_select_up_to_5.html.haml
239
172
  - app/views/effective/poll_results/results/_short_answer.html.haml
240
173
  - app/views/effective/poll_results/results/_upload_file.html.haml
241
- - app/views/effective/polls/_form.html.haml
242
- - app/views/effective/polls/_poll.html.haml
174
+ - app/views/effective/polls_mailer/poll_reminder.liquid
175
+ - app/views/effective/polls_mailer/poll_upcoming_reminder.liquid
176
+ - app/views/effective/polls_mailer/poll_when_poll_ends.liquid
177
+ - app/views/effective/polls_mailer/poll_when_poll_starts.liquid
243
178
  - app/views/layouts/effective_polls_mailer_layout.html.haml
244
179
  - config/effective_polls.rb
245
180
  - config/routes.rb
@@ -1,2 +0,0 @@
1
- %p= poll.title
2
- %p= poll.body
@@ -1,10 +0,0 @@
1
- = effective_form_with(model: poll, engine: true) do |f|
2
- = f.text_field :title, hint: 'The title of your poll.'
3
- = f.text_area :body
4
-
5
- = f.datetime_field :start_at
6
- = f.datetime_field :end_at
7
-
8
- = f.check_box :draft, hint: 'Save this poll as a draft. It will not be accessible on the website.'
9
-
10
- = effective_submit(f)
@@ -1,2 +0,0 @@
1
- %p= poll.title
2
- %p= poll.body