effective_polls 0.1.1 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/effective/ballots_controller.rb +1 -1
  3. data/app/datatables/admin/effective_poll_notifications_datatable.rb +2 -0
  4. data/app/datatables/admin/effective_poll_results_datatable.rb +1 -1
  5. data/app/mailers/effective/polls_mailer.rb +12 -1
  6. data/app/models/effective/ballot_response.rb +6 -6
  7. data/app/models/effective/poll_notification.rb +11 -5
  8. data/app/views/admin/poll_notifications/_form_poll_before_poll_ends.html.haml +8 -0
  9. data/app/views/effective/ballot_responses/fields/{_select_upto_1.html.haml → _select_up_to_1.html.haml} +0 -0
  10. data/app/views/effective/ballot_responses/fields/{_select_upto_2.html.haml → _select_up_to_2.html.haml} +0 -0
  11. data/app/views/effective/ballot_responses/fields/{_select_upto_3.html.haml → _select_up_to_3.html.haml} +0 -0
  12. data/app/views/effective/ballot_responses/fields/{_select_upto_4.html.haml → _select_up_to_4.html.haml} +0 -0
  13. data/app/views/effective/ballot_responses/fields/{_select_upto_5.html.haml → _select_up_to_5.html.haml} +0 -0
  14. data/app/views/effective/ballot_responses/responses/{_select_upto_1.html.haml → _select_up_to_1.html.haml} +0 -0
  15. data/app/views/effective/ballot_responses/responses/{_select_upto_2.html.haml → _select_up_to_2.html.haml} +0 -0
  16. data/app/views/effective/ballot_responses/responses/{_select_upto_3.html.haml → _select_up_to_3.html.haml} +0 -0
  17. data/app/views/effective/ballot_responses/responses/{_select_upto_4.html.haml → _select_up_to_4.html.haml} +0 -0
  18. data/app/views/effective/ballot_responses/responses/{_select_upto_5.html.haml → _select_up_to_5.html.haml} +0 -0
  19. data/app/views/effective/poll_results/results/{_select_upto_1.html.haml → _select_up_to_1.html.haml} +0 -0
  20. data/app/views/effective/poll_results/results/{_select_upto_2.html.haml → _select_up_to_2.html.haml} +0 -0
  21. data/app/views/effective/poll_results/results/{_select_upto_3.html.haml → _select_up_to_3.html.haml} +0 -0
  22. data/app/views/effective/poll_results/results/{_select_upto_4.html.haml → _select_up_to_4.html.haml} +0 -0
  23. data/app/views/effective/poll_results/results/{_select_upto_5.html.haml → _select_up_to_5.html.haml} +0 -0
  24. data/app/views/effective/polls_mailer/poll_before_poll_ends.liquid +13 -0
  25. data/lib/effective_polls/version.rb +1 -1
  26. metadata +19 -18
  27. data/app/models/effective/access_denied.rb +0 -17
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 564dabc8a5490be5d5ebf050a0b4e718b69781dcc9b7d585e8644546f54288cd
4
- data.tar.gz: 1503bc14d59cc2e1b1d7a9938065b5ac687eb8b81defcc594fc95b74b7284009
3
+ metadata.gz: 75f0f5786c67293ac7c6e5d8758334fe217c3d2b6361185ec36a8792fe751eaf
4
+ data.tar.gz: '08c11bd2988f3cf8c8ab81b3ffaa2fda3d445b7460004cd25d329ba984a81db5'
5
5
  SHA512:
6
- metadata.gz: 811446095aa021a4eed57a83047f79debbdab3c931184ff748c6c36181202691d7a5c845b4b5c364a984b5785d9f661d8ca56268eec807c5c6cf95905d250e2d
7
- data.tar.gz: 8e5e682feb705f6a4891b734610fac4c6e5a90ae897119f04c63c28bf32ea2479fb041ca8653bf32876974bb52dd8c72cdebf7e8d29fe47ba1230572ebef9cbd
6
+ metadata.gz: acfb2e71deb5da69bb9f37ccc6889cb93aee01624854e37537cadae80c19f49569fbc1d63080ca32c343595158e99a75833a9393efd1d9c311408151e2b4392d
7
+ data.tar.gz: 1adb90d91b12bed10d2eb7260080487eac8e5e2c689f171b0032a8dce139e4ddd7fe1e3f1a779826032cef0234b8b0fd1f7247c125e0c0a0c97364ac56c87056
@@ -19,7 +19,7 @@ module Effective
19
19
  flash[:danger] = 'You have already completed a ballot for this poll.'
20
20
  redirect_to(root_path)
21
21
  elsif existing.present?
22
- flash[:success] = "You have been redirected to the #{resource_wizard_step_title(existing.next_step)} step."
22
+ flash[:success] = "You have been redirected to the #{resource_wizard_step_title(existing, existing.next_step)} step."
23
23
  redirect_to effective_polls.poll_ballot_build_path(existing.poll, existing, existing.next_step)
24
24
  end
25
25
  end
@@ -23,6 +23,8 @@ class Admin::EffectivePollNotificationsDatatable < Effective::Datatable
23
23
  Effective::PollNotification::UPCOMING_REMINDERS.invert[poll_notification.reminder]
24
24
  when 'Reminder'
25
25
  Effective::PollNotification::REMINDERS.invert[poll_notification.reminder]
26
+ when 'Before poll ends'
27
+ Effective::PollNotification::UPCOMING_REMINDERS.invert[poll_notification.reminder]
26
28
  else
27
29
  raise('unexpected category')
28
30
  end
@@ -10,7 +10,7 @@ class Admin::EffectivePollResultsDatatable < Effective::Datatable
10
10
  end
11
11
 
12
12
  collection do
13
- ballot_responses = Effective::BallotResponse.completed.deep.where(poll: poll)
13
+ ballot_responses = Effective::BallotResponse.completed.deep.where(poll: poll, poll_question: poll.poll_questions)
14
14
 
15
15
  ballot_responses.flat_map do |br|
16
16
  rows = if br.poll_question.poll_question_option?
@@ -35,6 +35,17 @@ module Effective
35
35
  )
36
36
  end
37
37
 
38
+ def poll_before_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
+
38
49
  def poll_when_poll_ends(poll_notification, user)
39
50
  @assigns = effective_email_templates_assigns(poll_notification, user)
40
51
 
@@ -59,7 +70,7 @@ module Effective
59
70
  {
60
71
  available_date: poll.available_date,
61
72
  title: poll.title,
62
- url: effective_polls.new_poll_ballot_url(poll),
73
+ url: effective_polls.poll_url(poll),
63
74
  user: {
64
75
  name: user.to_s,
65
76
  email: user.email
@@ -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')
@@ -3,7 +3,7 @@ module Effective
3
3
  belongs_to :poll
4
4
  log_changes(to: :poll) if respond_to?(:log_changes)
5
5
 
6
- CATEGORIES = ['Upcoming reminder', 'When poll starts', 'Reminder', 'When poll ends']
6
+ CATEGORIES = ['Upcoming reminder', 'When poll starts', 'Reminder', 'Before poll ends', 'When poll ends']
7
7
  EMAIL_TEMPLATE_VARIABLES = ['available_date', 'title', 'url', 'user.name', 'user.email']
8
8
 
9
9
  UPCOMING_REMINDERS = {
@@ -77,7 +77,7 @@ module Effective
77
77
  validates :subject, liquid: true
78
78
  end
79
79
 
80
- validates :reminder, if: -> { reminder? || upcoming_reminder? },
80
+ validates :reminder, if: -> { reminder? || upcoming_reminder? || before_poll_ends? },
81
81
  presence: true, uniqueness: { scope: [:poll_id, :category], message: 'already exists' }
82
82
 
83
83
  def to_s
@@ -100,6 +100,10 @@ module Effective
100
100
  category == 'Reminder'
101
101
  end
102
102
 
103
+ def before_poll_ends?
104
+ category == 'Before poll ends'
105
+ end
106
+
103
107
  def poll_end?
104
108
  category == 'When poll ends'
105
109
  end
@@ -120,16 +124,18 @@ module Effective
120
124
  !poll.started? && poll.start_at < (Time.zone.now + reminder)
121
125
  when 'Reminder'
122
126
  !poll.ended? && poll.start_at < (Time.zone.now - reminder)
127
+ when 'Before poll ends'
128
+ !poll.ended? && poll.end_at.present? && poll.end_at < (Time.zone.now + reminder)
123
129
  else
124
130
  raise('unexpected category')
125
131
  end
126
132
  end
127
133
 
128
- def notify!
129
- return false unless notify_now?
134
+ def notify!(force: false)
135
+ return false unless (notify_now? || force)
130
136
 
131
137
  # We send to all users, except for the 'Reminder' that exclude completed users
132
- users = poll.users(except_completed: (category == 'Reminder'))
138
+ users = poll.users(except_completed: (category == 'Reminder' || category == 'Before poll ends'))
133
139
 
134
140
  update_column(:started_at, Time.zone.now)
135
141
 
@@ -0,0 +1,8 @@
1
+ = f.select :reminder, Effective::PollNotification::UPCOMING_REMINDERS, label: false,
2
+ hint: "before the poll ends on #{f.object.poll&.end_at&.strftime('%F') || 'never'}."
3
+
4
+ .alert.alert-warning
5
+ %strong Before Poll Ends
6
+ reminders are sent to users in the audience who have not yet completed their ballot.
7
+ %br
8
+ Use before poll ends notifications to remind people to vote.
@@ -0,0 +1,13 @@
1
+ ---
2
+ subject: 'Please submit your ballot for {{ title }}'
3
+ from: 'admin@example.com'
4
+ ---
5
+ Hello {{ user.name }},
6
+
7
+ The {{ title }} poll is almost complete.
8
+
9
+ Please remember to submit your ballot.
10
+
11
+ {{ url }}
12
+
13
+ Thank you
@@ -1,3 +1,3 @@
1
1
  module EffectivePolls
2
- VERSION = '0.1.1'
2
+ VERSION = '0.1.6'
3
3
  end
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.1.1
4
+ version: 0.1.6
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-02-11 00:00:00.000000000 Z
11
+ date: 2021-07-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -104,7 +104,6 @@ files:
104
104
  - app/datatables/effective_polls_datatable.rb
105
105
  - app/helpers/effective_polls_helper.rb
106
106
  - app/mailers/effective/polls_mailer.rb
107
- - app/models/effective/access_denied.rb
108
107
  - app/models/effective/ballot.rb
109
108
  - app/models/effective/ballot_response.rb
110
109
  - app/models/effective/ballot_response_option.rb
@@ -113,6 +112,7 @@ files:
113
112
  - app/models/effective/poll_question.rb
114
113
  - app/models/effective/poll_question_option.rb
115
114
  - app/views/admin/poll_notifications/_form.html.haml
115
+ - app/views/admin/poll_notifications/_form_poll_before_poll_ends.html.haml
116
116
  - app/views/admin/poll_notifications/_form_poll_reminder.html.haml
117
117
  - app/views/admin/poll_notifications/_form_poll_upcoming_reminder.html.haml
118
118
  - app/views/admin/poll_notifications/_form_poll_when_poll_ends.html.haml
@@ -130,11 +130,11 @@ files:
130
130
  - app/views/effective/ballot_responses/fields/_long_answer.html.haml
131
131
  - app/views/effective/ballot_responses/fields/_number.html.haml
132
132
  - app/views/effective/ballot_responses/fields/_select_all_that_apply.html.haml
133
- - app/views/effective/ballot_responses/fields/_select_upto_1.html.haml
134
- - app/views/effective/ballot_responses/fields/_select_upto_2.html.haml
135
- - app/views/effective/ballot_responses/fields/_select_upto_3.html.haml
136
- - app/views/effective/ballot_responses/fields/_select_upto_4.html.haml
137
- - 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
138
138
  - app/views/effective/ballot_responses/fields/_short_answer.html.haml
139
139
  - app/views/effective/ballot_responses/fields/_upload_file.html.haml
140
140
  - app/views/effective/ballot_responses/responses/_choose_one.html.haml
@@ -143,11 +143,11 @@ files:
143
143
  - app/views/effective/ballot_responses/responses/_long_answer.html.haml
144
144
  - app/views/effective/ballot_responses/responses/_number.html.haml
145
145
  - app/views/effective/ballot_responses/responses/_select_all_that_apply.html.haml
146
- - app/views/effective/ballot_responses/responses/_select_upto_1.html.haml
147
- - app/views/effective/ballot_responses/responses/_select_upto_2.html.haml
148
- - app/views/effective/ballot_responses/responses/_select_upto_3.html.haml
149
- - app/views/effective/ballot_responses/responses/_select_upto_4.html.haml
150
- - 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
151
151
  - app/views/effective/ballot_responses/responses/_short_answer.html.haml
152
152
  - app/views/effective/ballot_responses/responses/_upload_file.html.haml
153
153
  - app/views/effective/ballots/_ballot.html.haml
@@ -164,13 +164,14 @@ files:
164
164
  - app/views/effective/poll_results/results/_number.html.haml
165
165
  - app/views/effective/poll_results/results/_poll_question_option.html.haml
166
166
  - app/views/effective/poll_results/results/_select_all_that_apply.html.haml
167
- - app/views/effective/poll_results/results/_select_upto_1.html.haml
168
- - app/views/effective/poll_results/results/_select_upto_2.html.haml
169
- - app/views/effective/poll_results/results/_select_upto_3.html.haml
170
- - app/views/effective/poll_results/results/_select_upto_4.html.haml
171
- - 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
172
172
  - app/views/effective/poll_results/results/_short_answer.html.haml
173
173
  - app/views/effective/poll_results/results/_upload_file.html.haml
174
+ - app/views/effective/polls_mailer/poll_before_poll_ends.liquid
174
175
  - app/views/effective/polls_mailer/poll_reminder.liquid
175
176
  - app/views/effective/polls_mailer/poll_upcoming_reminder.liquid
176
177
  - app/views/effective/polls_mailer/poll_when_poll_ends.liquid
@@ -1,17 +0,0 @@
1
- unless defined?(Effective::AccessDenied)
2
- module Effective
3
- class AccessDenied < StandardError
4
- attr_reader :action, :subject
5
-
6
- def initialize(message = nil, action = nil, subject = nil)
7
- @message = message
8
- @action = action
9
- @subject = subject
10
- end
11
-
12
- def to_s
13
- @message || I18n.t(:'unauthorized.default', :default => 'Access Denied')
14
- end
15
- end
16
- end
17
- end