effective_polls 0.3.0 → 0.4.0

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 (46) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/admin/polls_controller.rb +1 -7
  3. data/app/controllers/effective/ballots_controller.rb +4 -1
  4. data/app/datatables/admin/effective_poll_notifications_datatable.rb +4 -1
  5. data/app/datatables/admin/effective_poll_results_datatable.rb +1 -4
  6. data/app/datatables/admin/effective_polls_datatable.rb +1 -0
  7. data/app/datatables/{effective_polls_datatable.rb → effective_polls_available_polls_datatable.rb} +6 -4
  8. data/app/helpers/effective_polls_helper.rb +17 -13
  9. data/app/mailers/effective/polls_mailer.rb +3 -1
  10. data/app/models/concerns/effective_polls_user.rb +67 -0
  11. data/app/models/effective/ballot.rb +11 -2
  12. data/app/models/effective/ballot_response.rb +1 -1
  13. data/app/models/effective/poll.rb +39 -26
  14. data/app/models/effective/poll_notification.rb +2 -2
  15. data/app/models/effective/poll_question.rb +1 -1
  16. data/app/models/effective/poll_question_option.rb +1 -1
  17. data/app/views/admin/poll_notifications/_form.html.haml +3 -5
  18. data/app/views/admin/poll_questions/_form.html.haml +12 -5
  19. data/app/views/admin/polls/_form.html.haml +10 -5
  20. data/app/views/admin/polls/_form_content.html.haml +16 -20
  21. data/app/views/admin/polls/_form_poll.html.haml +16 -7
  22. data/app/views/admin/polls/_poll.html.haml +5 -0
  23. data/app/views/effective/ballots/_content.html.haml +10 -0
  24. data/app/views/effective/ballots/_layout.html.haml +3 -0
  25. data/app/views/effective/ballots/complete.html.haml +13 -8
  26. data/app/views/effective/ballots/start.html.haml +29 -12
  27. data/app/views/effective/ballots/submit.html.haml +10 -13
  28. data/app/views/effective/ballots/vote.html.haml +10 -15
  29. data/app/views/effective/poll_results/_results.html.haml +2 -2
  30. data/app/views/effective/polls/_dashboard.html.haml +25 -0
  31. data/app/views/effective/polls_mailer/poll_before_poll_ends.liquid +0 -1
  32. data/app/views/effective/polls_mailer/poll_reminder.liquid +0 -1
  33. data/app/views/effective/polls_mailer/poll_upcoming_reminder.liquid +0 -1
  34. data/app/views/effective/polls_mailer/poll_when_poll_ends.liquid +0 -1
  35. data/app/views/effective/polls_mailer/poll_when_poll_starts.liquid +0 -1
  36. data/config/effective_polls.rb +2 -11
  37. data/config/locales/effective_polls.yml +14 -0
  38. data/config/routes.rb +2 -5
  39. data/db/migrate/101_create_effective_polls.rb +12 -10
  40. data/db/seeds.rb +2 -1
  41. data/lib/effective_polls/engine.rb +7 -0
  42. data/lib/effective_polls/version.rb +1 -1
  43. data/lib/effective_polls.rb +2 -4
  44. data/lib/tasks/effective_polls_tasks.rake +23 -12
  45. metadata +9 -4
  46. data/app/views/admin/polls/results.html.haml +0 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '092395996d087f516aca9b5aa9f42e170c56702b0dd9c7c7479332cb18a0c2c7'
4
- data.tar.gz: 316a9df7d201ed389316f1cc11c5a77310038957520bdaf711666bfcf867ed7a
3
+ metadata.gz: 637320f25a72489ada773806629e70590bb5c8435e871a6de40497e2eb6300ed
4
+ data.tar.gz: e797d1afdad6be66099b291ec7a809cbb65ef32d7963ca04f03d3ac3d91fe2a9
5
5
  SHA512:
6
- metadata.gz: d4f8a181881338bd4f274194770d82fb632f0456910d1df843ec404025d4eaceb219fca21215e70d44c278a6f1791dff199fbab9b3cd2f6e88fadc6498fbfa7a
7
- data.tar.gz: 7dae7c572c9236edcae987f7d3a4e1afce6cd65557890a82c81797b7a7d12816157020d0966379c3f70322d08ffdc7a0bde593c755ffe824153e3a97a4be3a4f
6
+ metadata.gz: 7317013d4063bdd11eaf4a72b6d5ca964c7acb2c35ac29653e9c7043c4e4c40de4e1b4b55079ed023b758f08982a51ca17926e37c5abafbca2462cf0b4a9e657
7
+ data.tar.gz: d3fe9a3b04a9ca98c5a27fa956fb82d536db6b9662b6d61a0e8fd954f603673384f6d70c3ec33e51fabde548063b126892508e858be72e616d2c9ff30318e732
@@ -5,13 +5,7 @@ module Admin
5
5
 
6
6
  include Effective::CrudController
7
7
 
8
- def results
9
- @poll = Effective::Poll.find(params[:id])
10
- EffectiveResources.authorize!(self, :results, @poll)
11
-
12
- @datatable = Admin::EffectivePollResultsDatatable.new(poll_token: @poll.token)
13
- @page_title = "#{@poll} Results"
14
- end
8
+ on :save, only: :create, redirect: :edit
15
9
 
16
10
  def permitted_params
17
11
  params.require(:effective_poll).permit!
@@ -1,6 +1,9 @@
1
1
  module Effective
2
2
  class BallotsController < ApplicationController
3
- before_action(:authenticate_user!) if defined?(Devise)
3
+
4
+ if defined?(Devise)
5
+ before_action :authenticate_user!, unless: -> { action_name == 'new' || (action_name == 'show' && params[:id] == 'start') }
6
+ end
4
7
 
5
8
  include Effective::WizardController
6
9
 
@@ -31,7 +31,10 @@ class Admin::EffectivePollNotificationsDatatable < Effective::Datatable
31
31
  end
32
32
 
33
33
  col :subject
34
- col :body
34
+
35
+ col :body do |notification|
36
+ simple_format(notification.body.to_s)
37
+ end
35
38
 
36
39
  col :started_at, visible: false
37
40
  col :completed_at
@@ -41,10 +41,7 @@ class Admin::EffectivePollResultsDatatable < Effective::Datatable
41
41
  end
42
42
 
43
43
  def poll
44
- @poll ||= begin
45
- raise('expected datatable poll_token attribute') unless attributes[:poll_token]
46
- Effective::Poll.deep_results.find(attributes[:poll_token])
47
- end
44
+ @poll ||= Effective::Poll.deep_results.where(id: attributes[:poll_id]).first!
48
45
  end
49
46
 
50
47
  end
@@ -18,6 +18,7 @@ class Admin::EffectivePollsDatatable < Effective::Datatable
18
18
  col :end_at
19
19
  col :audience
20
20
 
21
+ col :poll_notifications
21
22
  col :poll_questions, visible: false
22
23
 
23
24
  actions_col
@@ -1,13 +1,14 @@
1
+ # Dashboard available polls
1
2
  # Displays available polls that the current_user may complete
2
3
 
3
- class EffectivePollsDatatable < Effective::Datatable
4
+ class EffectivePollsAvailablePollsDatatable < Effective::Datatable
4
5
  datatable do
5
6
  order :start_at
6
7
 
7
8
  col :start_at, visible: false
8
9
 
9
10
  col :title
10
- col :available_date, label: 'Date'
11
+ col :available_date
11
12
 
12
13
  actions_col(actions: []) do |poll|
13
14
  ballot = poll.ballots.where(user: current_user).first
@@ -15,16 +16,17 @@ class EffectivePollsDatatable < Effective::Datatable
15
16
  if ballot.blank?
16
17
  dropdown_link_to('Start', effective_polls.poll_ballot_build_path(poll, :new, :start))
17
18
  elsif ballot.completed?
19
+ #dropdown_link_to('Show', effective_polls.poll_ballot_path(poll, ballot))
18
20
  'Complete'
19
21
  else
20
22
  dropdown_link_to('Continue', effective_polls.poll_ballot_build_path(poll, ballot, ballot.next_step))
23
+ dropdown_link_to('Delete', effective_polls.poll_ballot_path(poll, ballot), 'data-confirm': "Really delete #{ballot}?", 'data-method': :delete)
21
24
  end
22
25
  end
23
26
  end
24
27
 
25
28
  collection do
26
- raise('expected a current_user') unless current_user.present?
27
- Effective::Poll.available.select { |poll| poll.available_for?(current_user) }
29
+ Effective::Poll.where(id: current_user.available_polls)
28
30
  end
29
31
 
30
32
  end
@@ -1,22 +1,26 @@
1
1
  module EffectivePollsHelper
2
2
 
3
+ # Used on dashboard
4
+ def polls_name_label
5
+ et('effective_polls.name')
6
+ end
7
+
3
8
  # Used by admin/polls form
4
- def effective_polls_audience_scope_collection
5
- # Normalize the collection into [[label, value], [label, value]]
6
- scopes = Array(EffectivePolls.audience_user_scopes).map do |key, value|
7
- (key.present? && value.present?) ? [key, value] : [key.to_s.titleize, key]
8
- end
9
+ def effective_polls_audience_scope_collection(poll)
10
+ klass = poll.try(:audience_class)
11
+ raise('expected a poll with an audience_class') unless klass.try(:effective_polls_user?)
9
12
 
10
- # Makes sure the User model responds to all values
11
- scopes.each do |_, scope|
12
- unless defined?(User) && User.respond_to?(scope)
13
- raise("invalid effective_polls config.audience_user_scopes value. The user model must respond to the scope User.#{scope}")
14
- end
15
- end
13
+ resource = klass.new
14
+
15
+ scopes = resource.poll_audience_scopes
16
+ raise('expected poll audience scopes') unless scopes.kind_of?(Array)
16
17
 
17
18
  # Append the number of users in this scope
18
- scopes.map! do |label, scope|
19
- ["#{label} (#{pluralize(User.send(scope).count, 'user')})", scope]
19
+ scopes.map do |label, scope|
20
+ relation = resource.poll_audience_scope(scope)
21
+ raise("invalid poll_audience_scope for #{scope}") unless relation.kind_of?(ActiveRecord::Relation)
22
+
23
+ ["#{label} (#{pluralize(relation.count, 'user')})", scope]
20
24
  end
21
25
  end
22
26
 
@@ -75,7 +75,9 @@ module Effective
75
75
  title: poll.title,
76
76
  url: effective_polls.poll_url(poll),
77
77
  user: {
78
- name: user.to_s,
78
+ name: (user.try(:email_to_s) || user.to_s),
79
+ first_name: user.try(:first_name).to_s,
80
+ last_name: user.try(:last_name).to_s,
79
81
  email: user.email
80
82
  }
81
83
  }
@@ -0,0 +1,67 @@
1
+ # EffectivePollsUser
2
+ #
3
+ # Mark your user model with effective_polls_user to get all the includes
4
+
5
+ module EffectivePollsUser
6
+ extend ActiveSupport::Concern
7
+
8
+ module Base
9
+ def effective_polls_user
10
+ include ::EffectivePollsUser
11
+ end
12
+ end
13
+
14
+ module ClassMethods
15
+ def effective_polls_user?; true; end
16
+ end
17
+
18
+ included do
19
+ has_many :ballots, -> { Effective::Ballot.sorted }, inverse_of: :user, as: :user, class_name: 'Effective::Ballot'
20
+ end
21
+
22
+ # The list of all available audience scopes for the Poll Selected Users
23
+ def poll_audience_scopes
24
+ scopes = [
25
+ ['All Users', :all]
26
+ ]
27
+
28
+ if self.class.try(:effective_memberships_user?)
29
+ scopes += [
30
+ ['All members', :members],
31
+ ['All removed members', :membership_removed],
32
+ ['All members in good standing', :membership_in_good_standing],
33
+ ['All members not in good standing', :membership_not_in_good_standing],
34
+ ['All members renewed this period', :membership_renewed_this_period],
35
+ ]
36
+
37
+ scopes += EffectiveMemberships.Category.sorted.map do |category|
38
+ ["All #{category} members", "members_with_category_id_#{category.id}"]
39
+ end
40
+ end
41
+
42
+ scopes
43
+ end
44
+
45
+ # Turns the given audience_scope value into the actual ActiveRecord::Relation scope
46
+ def poll_audience_scope(value)
47
+ collection = self.class.respond_to?(:unarchived) ? self.class.unarchived : self.class
48
+
49
+ # If we respond to the fill value, call it
50
+ return collection.send(value) if collection.respond_to?(value)
51
+
52
+ # Parse the value
53
+ name, id = value.to_s.split('_id_')
54
+
55
+ case name.try(:to_sym)
56
+ when :members_with_category
57
+ collection.members_with_category(EffectiveMemberships.Category.find(id))
58
+ else
59
+ raise("unknown poll_audience_scope for #{value}")
60
+ end
61
+ end
62
+
63
+ def available_polls
64
+ Effective::Poll.available.select { |poll| poll.available_for?(self) }
65
+ end
66
+
67
+ end
@@ -3,14 +3,19 @@ module Effective
3
3
  attr_accessor :current_user
4
4
  attr_accessor :current_step
5
5
 
6
+ # Application namespace
7
+ belongs_to :user, polymorphic: true
8
+
9
+ # Effective namespace
6
10
  belongs_to :poll
7
- belongs_to :user
8
11
 
9
12
  has_many :ballot_responses, dependent: :destroy
10
13
  accepts_nested_attributes_for :ballot_responses
11
14
 
12
15
  acts_as_tokened
13
16
 
17
+ log_changes(to: :poll) if respond_to?(:log_changes)
18
+
14
19
  acts_as_wizard(
15
20
  start: 'Start',
16
21
  vote: 'Ballot',
@@ -34,6 +39,10 @@ module Effective
34
39
 
35
40
  scope :deep, -> { includes(:poll, :user, ballot_responses: [:poll, :poll_question, :poll_question_options]) }
36
41
  scope :sorted, -> { order(:id) }
42
+
43
+ scope :in_progress, -> { where(completed_at: nil) }
44
+ scope :done, -> { where.not(completed_at: nil) }
45
+
37
46
  scope :completed, -> { where.not(completed_at: nil) }
38
47
 
39
48
  before_validation(if: -> { new_record? }) do
@@ -48,7 +57,7 @@ module Effective
48
57
  validates :ballot_responses, associated: true
49
58
 
50
59
  def to_s
51
- 'ballot'
60
+ model_name.human
52
61
  end
53
62
 
54
63
  # Find or build
@@ -64,7 +64,7 @@ module Effective
64
64
  length: { maximum: 5, message: 'please select 5 options or fewer' }
65
65
 
66
66
  def to_s
67
- 'ballot reponse'
67
+ model_name.human
68
68
  end
69
69
 
70
70
  def response
@@ -1,10 +1,6 @@
1
1
  module Effective
2
2
  class Poll < ActiveRecord::Base
3
- has_rich_text :all_steps_content
4
- has_rich_text :start_content
5
- has_rich_text :vote_content
6
- has_rich_text :submit_content
7
- has_rich_text :complete_content
3
+ acts_as_tokened
8
4
 
9
5
  has_many :poll_notifications, -> { order(:id) }, inverse_of: :poll, dependent: :destroy
10
6
  accepts_nested_attributes_for :poll_notifications, allow_destroy: true
@@ -19,7 +15,12 @@ module Effective
19
15
  has_many :completed_ballots, -> { Effective::Ballot.completed }, class_name: 'Effective::Ballot'
20
16
  has_many :completed_ballot_responses, -> { where(ballot: Effective::Ballot.completed) }, class_name: 'Effective::BallotResponse'
21
17
 
22
- acts_as_tokened
18
+ has_many_rich_texts
19
+ # rich_text_all_steps_content
20
+ # rich_text_start_content
21
+ # rich_text_vote_content
22
+ # rich_text_submit_content
23
+ # rich_text_complete_content
23
24
 
24
25
  if respond_to?(:log_changes)
25
26
  log_changes(except: [:ballots, :ballot_responses, :completed_ballots, :completed_ballot_responses])
@@ -29,29 +30,23 @@ module Effective
29
30
 
30
31
  effective_resource do
31
32
  # Acts as tokened
32
- token :string, permitted: false
33
+ token :string, permitted: false
33
34
 
34
35
  title :string
35
36
 
36
37
  start_at :datetime
37
38
  end_at :datetime
38
39
 
39
- audience :string
40
- audience_scope :text # An Array of user_ids or named scopes on the User model
40
+ audience :string
41
+ audience_class_name :string
42
+ audience_scope :text # An Array of user_ids or named scopes on the User model
41
43
 
42
44
  timestamps
43
45
  end
44
46
 
45
47
  serialize :audience_scope, Array
46
48
 
47
- scope :deep, -> {
48
- includes(poll_questions: :poll_question_options)
49
- .with_rich_text_all_steps_content
50
- .with_rich_text_start_content
51
- .with_rich_text_vote_content
52
- .with_rich_text_submit_content
53
- .with_rich_text_complete_content
54
- }
49
+ scope :deep, -> { includes(poll_questions: :poll_question_options) }
55
50
 
56
51
  scope :deep_results, -> {
57
52
  includes(poll_questions: :poll_question_options)
@@ -68,6 +63,8 @@ module Effective
68
63
  validates :start_at, presence: true
69
64
 
70
65
  validates :audience, inclusion: { in: AUDIENCES }
66
+ validates :audience_class_name, presence: true
67
+
71
68
  validates :audience_scope, presence: true, unless: -> { audience == 'All Users' }
72
69
 
73
70
  validate(if: -> { start_at.present? && end_at.present? }) do
@@ -75,33 +72,49 @@ module Effective
75
72
  end
76
73
 
77
74
  def to_s
78
- title.presence || 'New Poll'
75
+ title.presence || model_name.human
79
76
  end
80
77
 
81
78
  def available_for?(user)
82
- raise('expected a user') unless user.kind_of?(User)
79
+ raise('expected an effective_polls_user') unless user.class.try(:effective_polls_user?)
83
80
  available? && users.include?(user)
84
81
  end
85
82
 
83
+ def audience_class
84
+ klass = audience_class_name.safe_constantize
85
+ raise('expected an effective_polls_user klass') unless klass.try(:effective_polls_user?)
86
+ klass
87
+ end
88
+
86
89
  def users(except_completed: false)
90
+ klass = audience_class()
91
+ resource = klass.new
92
+
87
93
  users = case audience
88
94
  when 'All Users'
89
- User.all
95
+ klass.try(:unarchived) || klass.all
90
96
  when 'Individual Users'
91
- User.where(id: audience_scope)
97
+ (klass.try(:unarchived) || klass.all).where(id: audience_scope)
92
98
  when 'Selected Users'
93
- collection = User.none
94
- audience_scope.each { |scope| collection = collection.or(User.send(scope)) }
99
+ collection = klass.none
100
+
101
+ audience_scope.each do |scope|
102
+ relation = resource.poll_audience_scope(scope)
103
+ raise("invalid poll_audience_scope for #{scope}") unless relation.kind_of?(ActiveRecord::Relation)
104
+
105
+ collection = collection.or(relation)
106
+ end
107
+
95
108
  collection
96
109
  else
97
110
  raise('unexpected audience')
98
111
  end
99
112
 
100
113
  if except_completed
101
- users.where.not(id: completed_ballots.select('user_id as id'))
102
- else
103
- users
114
+ users = users.where.not(id: completed_ballots.select('user_id as id'))
104
115
  end
116
+
117
+ users
105
118
  end
106
119
 
107
120
  def available?
@@ -72,7 +72,7 @@ module Effective
72
72
  validates :subject, presence: true
73
73
  validates :body, presence: true
74
74
 
75
- if EffectivePolls.use_effective_email_templates
75
+ with_options(if: -> { EffectivePolls.use_effective_email_templates }) do
76
76
  validates :body, liquid: true
77
77
  validates :subject, liquid: true
78
78
  end
@@ -81,7 +81,7 @@ module Effective
81
81
  presence: true, uniqueness: { scope: [:poll_id, :category], message: 'already exists' }
82
82
 
83
83
  def to_s
84
- 'poll notification'
84
+ [category.presence, subject.presence].compact.join(' - ') || model_name.human
85
85
  end
86
86
 
87
87
  def email_template
@@ -62,7 +62,7 @@ module Effective
62
62
  end
63
63
 
64
64
  def to_s
65
- title.presence || 'New Poll Question'
65
+ title.presence || model_name.human
66
66
  end
67
67
 
68
68
  def poll_question_option?
@@ -19,7 +19,7 @@ module Effective
19
19
  validates :position, presence: true
20
20
 
21
21
  def to_s
22
- title.presence || 'New Poll Question Option'
22
+ title.presence || model_name.human
23
23
  end
24
24
 
25
25
  end
@@ -12,22 +12,20 @@
12
12
  - template = 'poll_' + category.parameterize.underscore
13
13
 
14
14
  = f.show_if :category, category do
15
- = render "/admin/poll_notifications/form_#{template}", f: f
15
+ .my-3= render "/admin/poll_notifications/form_#{template}", f: f
16
+
17
+ = f.select :from, EffectivePolls.mailer_froms
16
18
 
17
19
  - if f.object.category == category
18
- = f.email_field :from
19
20
  = f.text_field :subject
20
21
  = f.text_area :body, rows: 10
21
22
 
22
23
  - elsif EffectivePolls.use_effective_email_templates == false
23
- = f.email_field :from, value: EffectivePolls.mailer[:default_from]
24
24
  = f.text_field :subject, value: ''
25
25
  = f.text_area :body, rows: 10, value: ''
26
26
 
27
27
  - else
28
28
  - email_template = Effective::EmailTemplate.where(template_name: template).first!
29
-
30
- = f.email_field :from, value: email_template.from
31
29
  = f.text_field :subject, value: email_template.subject
32
30
  = f.text_area :body, rows: 10, value: email_template.body
33
31
 
@@ -2,19 +2,26 @@
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.all
6
6
 
7
7
  = f.text_field :title, label: 'Question Title'
8
- = f.rich_text_area :body, label: 'Body (optional)'
8
+
9
+ - if defined?(EffectiveArticleEditor)
10
+ = f.article_editor :body, label: 'Body (optional)'
11
+ - else
12
+ = f.rich_text_area :body, label: 'Body (optional)'
9
13
 
10
14
  = f.check_box :required, hint: 'A response to this question will be required'
11
15
  = f.select :category, Effective::PollQuestion::CATEGORIES
12
16
 
13
17
  = f.show_if :category, 'Choose one' do
14
- .card
18
+ .mt-3.card
15
19
  .card-body
16
- %h5 Choose one
17
- %p Display radio buttons to choose one option
20
+ %h5 Options
21
+ %p Display the following options:
22
+
23
+ = f.has_many :poll_question_options, build: true do |fa|
24
+ = fa.text_field :title, label: false
18
25
 
19
26
  = f.show_if :category, 'Select all that apply' do
20
27
  .card
@@ -7,18 +7,23 @@
7
7
  = render 'admin/polls/form_content', poll: poll
8
8
 
9
9
  = tab 'Questions' do
10
- - datatable = Admin::EffectivePollQuestionsDatatable.new(poll_id: poll.id)
10
+ - datatable = Admin::EffectivePollQuestionsDatatable.new(poll: poll)
11
11
  = render_datatable(datatable, inline: true, simple: true)
12
12
 
13
13
  = tab 'Notifications' do
14
14
  %p
15
15
  The following email notifications will be sent to
16
- = pluralize(poll.users.count, 'users')
16
+ = pluralize(poll.users.count, 'user')
17
17
  in the audience.
18
18
 
19
- - datatable = Admin::EffectivePollNotificationsDatatable.new(poll_id: poll.id)
19
+ %p
20
+ The url for this #{et(poll)} is:
21
+ - url = effective_polls.poll_url(poll)
22
+ = link_to(url, url, target: '_blank')
23
+
24
+ - datatable = Admin::EffectivePollNotificationsDatatable.new(poll: poll)
20
25
  = render_datatable(datatable, inline: true, simple: true)
21
26
 
22
- - if poll.respond_to?(:log_changes_datatable)
27
+ - if poll.respond_to?(:logs_datatable)
23
28
  = tab 'Logs' do
24
- = render_datatable(poll.log_changes_datatable)
29
+ = render_datatable(poll.logs_datatable)
@@ -1,27 +1,23 @@
1
+ %p Each of the following content areas will be displayed on the ballot wizard.
2
+
1
3
  = effective_form_with(model: [:admin, poll], engine: true) do |f|
2
- .card.mb-4
3
- .card-body
4
- %h5.card-title All Steps Content
5
- = f.rich_text_area :all_steps_content, label: false, hint: 'displayed on all ballot steps'
4
+ = card("All Steps") do
5
+ - if defined?(EffectiveArticleEditor)
6
+ = f.article_editor "rich_text_all_steps_content", label: false, hint: "displayed on all steps"
7
+ - else
8
+ = f.rich_text_area "rich_text_all_steps_content", label: false, hint: "displayed on all steps"
6
9
 
7
- .card.mb-4
8
- .card-body
9
- %h5.card-title Start Step
10
- = f.rich_text_area :start_content, label: false, hint: 'displayed on the start step only'
10
+ %hr
11
11
 
12
- .card.mb-4
13
- .card-body
14
- %h5.card-title Vote Step
15
- = f.rich_text_area :vote_content, label: false, hint: 'displayed on the vote step only'
12
+ - enabled = Effective::Ballot.all_wizard_steps
16
13
 
17
- .card.mb-4
18
- .card-body
19
- %h5.card-title Review and Submit Step
20
- = f.rich_text_area :submit_content, label: false, hint: 'displayed on the review and submit step only'
14
+ - Effective::Ballot::WIZARD_STEPS.each do |step, title|
15
+ - next unless enabled.include?(step)
21
16
 
22
- .card.mb-4
23
- .card-body
24
- %h5.card-title Complete Step
25
- = f.rich_text_area :complete_content, label: false, hint: 'displayed on the complete step only'
17
+ = card("#{title}") do
18
+ - if defined?(EffectiveArticleEditor)
19
+ = f.article_editor "rich_text_#{step}_content", label: false, hint: "displayed on the ballot #{step} wizard step only"
20
+ - else
21
+ = f.rich_text_area "rich_text_#{step}_content", label: false, hint: "displayed on the ballot #{step} wizard step only"
26
22
 
27
23
  = f.submit
@@ -1,32 +1,41 @@
1
1
  = effective_form_with(model: [:admin, poll], engine: true) do |f|
2
+
2
3
  = f.text_field :title, hint: 'The title of your poll or election.'
3
4
 
4
- = f.datetime_field :start_at, input_js: { minDate: Time.zone.now.beginning_of_day.strftime('%F') }
5
+ = f.datetime_field :start_at
5
6
  = f.datetime_field :end_at
6
7
 
8
+ - if f.object.poll_notifications.present?
9
+ .alert.alert-info
10
+ Please be aware of the existing #{ets(f.object.poll_notifications)} when changing the start or end availability date.
11
+
7
12
  -# Audience
13
+ - f.object.audience_class_name ||= current_user.class.name
14
+
15
+ = f.hidden_field :audience_class_name
8
16
  = f.radios :audience, Effective::Poll::AUDIENCES
9
17
 
10
18
  = f.show_if :audience, 'All Users' do
11
19
  .card
12
20
  .card-body
13
21
  %h5 All Users
14
- %p All users may complete this poll
22
+ %p All users may complete this #{etd(poll)}
15
23
 
16
24
  = f.show_if :audience, 'Individual Users' do
17
25
  .card
18
26
  .card-body
19
27
  %h5 Individual Users
20
- %p Only the following individual users may complete this poll
28
+ %p Only the following individual users may complete this #{etd(poll)}
21
29
 
22
- - user_ids = User.respond_to?(:sorted) ? User.sorted : User.all
23
- = f.select :audience_scope, user_ids, multiple: true, label: false
30
+ -# Audience Users
31
+ - ajax_url = (@select2_users_ajax_path || effective_resources.users_admin_select2_ajax_index_path) unless Rails.env.test?
32
+ = f.select :audience_scope, current_user.class.all, ajax_url: ajax_url, multiple: true
24
33
 
25
34
  = f.show_if :audience, 'Selected Users' do
26
35
  .card
27
36
  .card-body
28
37
  %h5 Selected Users
29
- %p Users within any of the following groups may complete this poll
30
- = f.checks :audience_scope, effective_polls_audience_scope_collection(), multiple: true, label: false
38
+ %p Users within any of the following groups may complete this #{etd(poll)}
39
+ = f.checks :audience_scope, effective_polls_audience_scope_collection(f.object), multiple: true, label: false
31
40
 
32
41
  = effective_submit(f)
@@ -0,0 +1,5 @@
1
+ = render 'effective/poll_results/results', poll: @poll
2
+
3
+ = card('Raw Data') do
4
+ - datatable = Admin::EffectivePollResultsDatatable.new(poll: @poll)
5
+ = render_datatable(datatable)
@@ -0,0 +1,10 @@
1
+ - all_steps_content = resource.poll&.rich_text_all_steps_content
2
+ - step_content = resource.poll&.send("rich_text_#{step}_content")
3
+
4
+ - if all_steps_content.present?
5
+ .card.mb-4
6
+ .card-body= all_steps_content.to_s
7
+
8
+ - if step_content.present?
9
+ .card.mb-4
10
+ .card-body= step_content.to_s
@@ -0,0 +1,3 @@
1
+ .row
2
+ .col-lg-3.mb-3= render_wizard_sidebar(resource)
3
+ .col-lg-9= yield
@@ -1,11 +1,16 @@
1
- = render_wizard_sidebar(resource) do
2
- %h1= @page_title
1
+ = render 'layout' do
2
+ = render 'effective/ballots/content', resource: resource
3
3
 
4
- - if resource.poll.all_steps_content.present?
5
- .mb-2= resource.poll.all_steps_content
4
+ - raise('expected a completed? poll') unless resource.completed?
6
5
 
7
- - if resource.poll.complete_content.present?
8
- .mb-2= resource.poll.complete_content
6
+ .alert.alert-warning.mb-4
7
+ Successfully completed on #{resource.completed_at.strftime('%F')}.
9
8
 
10
- .text-center
11
- %p= link_to 'Home', root_path, class: 'btn btn-primary'
9
+ .mb-4
10
+ = link_to "Return to Dashboard", return_to_dashboard_path, class: 'btn btn-lg btn-primary btn-block'
11
+
12
+ = card do
13
+ %p= resource.poll
14
+ = render 'effective/ballots/ballot', ballot: resource
15
+
16
+ = link_to "Return to Dashboard", return_to_dashboard_path, class: 'btn btn-lg btn-primary btn-block'
@@ -1,17 +1,34 @@
1
- = render_wizard_sidebar(resource) do
2
- %h1= resource.poll
1
+ = render 'layout' do
2
+ = render 'effective/ballots/content', resource: resource
3
3
 
4
- .alert.alert-warning
5
- This is a <strong>Secret Ballot</strong>.
6
- Only you will know what you have submitted and no one has access to individual ballots.
4
+ - # Signed out
5
+ - if resource.user.blank?
6
+ = card do
7
+ %p Welcome!
7
8
 
8
- - if resource.poll.all_steps_content.present?
9
- .mb-2= resource.poll.all_steps_content
9
+ %p You are about to register for #{resource.poll}.
10
10
 
11
- - if resource.poll.start_content.present?
12
- .mb-2= resource.poll.start_content
11
+ %p
12
+ Please
13
+ = link_to 'sign in', '/users/sign_in'
14
+ or
15
+ = link_to 'sign up', '/users/sign_up'
16
+ to continue.
17
+
18
+ %p= link_to 'Sign In to Continue', '/users/sign_in', class: 'btn btn-primary'
13
19
 
14
- = effective_form_with(model: resource, url: wizard_path(step), method: :put) do |f|
15
- = f.hidden_field :current_step
20
+ - # Signed in
21
+ - if resource.user.present?
22
+ .alert.alert-warning.mb-4
23
+ This is a <strong>Secret Ballot</strong>.
24
+ Only you will know what you have submitted and no one has access to individual ballots.
16
25
 
17
- = f.submit 'Start', center: true
26
+ = card do
27
+ %p Welcome #{current_user}!
28
+
29
+ %p You are starting a #{etd(resource.poll)} for #{resource.poll}.
30
+
31
+ = effective_form_with(model: resource, url: wizard_path(step), method: :put) do |f|
32
+ = f.hidden_field :current_step
33
+
34
+ = f.submit 'Start', center: true
@@ -1,17 +1,14 @@
1
- = render_wizard_sidebar(resource) do
2
- %h1= resource.poll
1
+ = render 'layout' do
2
+ = render 'effective/ballots/content', resource: resource
3
3
 
4
- - if resource.poll.all_steps_content.present?
5
- .mb-2= resource.poll.all_steps_content
4
+ = card do
5
+ %p= resource.poll
6
6
 
7
- - if resource.poll.submit_content.present?
8
- .mb-2= resource.poll.submit_content
7
+ = effective_form_with(model: resource, url: wizard_path(step), method: :put) do |f|
8
+ = f.hidden_field :current_step
9
9
 
10
- = effective_form_with(model: resource, url: wizard_path(step), method: :put) do |f|
11
- = f.hidden_field :current_step
10
+ = render(resource)
12
11
 
13
- = render(resource)
14
-
15
- = f.submit(center: true) do
16
- = link_to 'Change Ballot', wizard_path(:vote), class: 'btn btn-secondary'
17
- = f.save 'Submit Ballot'
12
+ = f.submit(center: true) do
13
+ = link_to 'Change Ballot', wizard_path(:vote), class: 'btn btn-secondary'
14
+ = f.save 'Submit Ballot'
@@ -1,19 +1,14 @@
1
- = render_wizard_sidebar(resource) do
2
- %h1= resource.poll
1
+ = render 'layout' do
2
+ = render 'effective/ballots/content', resource: resource
3
3
 
4
- - if resource.poll.all_steps_content.present?
5
- .mb-2= resource.poll.all_steps_content
4
+ = card do
5
+ = effective_form_with(model: resource, url: wizard_path(step), method: :put) do |f|
6
+ = f.hidden_field :current_step
6
7
 
7
- - if resource.poll.vote_content.present?
8
- .mb-2= resource.poll.vote_content
8
+ - resource.poll.poll_questions.deep.all.each_with_index do |poll_question, index|
9
+ - ballot_response = resource.ballot_response(poll_question)
9
10
 
10
- = effective_form_with(model: resource, url: wizard_path(step), method: :put) do |f|
11
- = f.hidden_field :current_step
11
+ = f.fields_for :ballot_responses, ballot_response do |fbr|
12
+ = render('/effective/ballot_responses/fields', f: fbr, poll_question: poll_question)
12
13
 
13
- - resource.poll.poll_questions.deep.all.each_with_index do |poll_question, index|
14
- - ballot_response = resource.ballot_response(poll_question)
15
-
16
- = f.fields_for :ballot_responses, ballot_response do |fbr|
17
- = render('/effective/ballot_responses/fields', f: fbr, poll_question: poll_question)
18
-
19
- = f.submit 'Save and Continue', center: true
14
+ = f.submit 'Save and Continue', center: true
@@ -6,11 +6,11 @@
6
6
 
7
7
  %p
8
8
  %strong
9
- = pluralize(poll.completed_ballots.count, 'users')
9
+ = pluralize(poll.completed_ballots.count, 'user')
10
10
  completed
11
11
  ballots from an audience of
12
12
  = succeed('.') do
13
- %strong= pluralize(poll.users.count, 'total users')
13
+ %strong= pluralize(poll.users.count, 'total user')
14
14
 
15
15
  .card.mb-3
16
16
  .card-body
@@ -0,0 +1,25 @@
1
+ -# In progress ballot
2
+ - ballot = Effective::Ballot.in_progress.where(user: current_user).first
3
+ - datatable = EffectiveResources.best('EffectivePollsAvailablePollsDatatable').new(self, namespace: :effective)
4
+
5
+ - if ballot.present?
6
+ %h2 In Progress #{et(Effective::Ballot)}
7
+
8
+ %p Your submission for #{ballot.poll} is incomplete
9
+
10
+ %p
11
+ Please
12
+ = link_to("Continue #{ballot.poll}", effective_polls.poll_ballot_build_path(ballot.poll, ballot, ballot.next_step), 'data-turbolinks' => false, class: 'btn btn-primary')
13
+ or you can
14
+ = link_to('Abandon', effective_polls.poll_ballot_path(ballot.poll, ballot), 'data-confirm': "Really delete #{ballot}?", 'data-method': :delete, class: 'btn btn-danger')
15
+ to begin again.
16
+
17
+ %hr
18
+
19
+ %h2 #{polls_name_label}
20
+
21
+ - if datatable.present?
22
+ %p The following #{etsd(Effective::Poll)} are available:
23
+ = render_datatable(datatable, simple: true)
24
+ - else
25
+ %p There are no available #{etsd(Effective::Poll)}. When there are, we'll show them here.
@@ -1,6 +1,5 @@
1
1
  ---
2
2
  subject: 'Please submit your ballot for {{ title }}'
3
- from: 'admin@example.com'
4
3
  ---
5
4
  Hello {{ user.name }},
6
5
 
@@ -1,6 +1,5 @@
1
1
  ---
2
2
  subject: 'Reminder - Please submit your ballot for {{ title }}'
3
- from: 'admin@example.com'
4
3
  ---
5
4
  Hello {{ user.name }},
6
5
 
@@ -1,6 +1,5 @@
1
1
  ---
2
2
  subject: '{{ title }} is upcoming'
3
- from: 'admin@example.com'
4
3
  ---
5
4
  Hello {{ user.name }},
6
5
 
@@ -1,6 +1,5 @@
1
1
  ---
2
2
  subject: '{{ title }} has ended'
3
- from: 'admin@example.com'
4
3
  ---
5
4
  Hello {{ user.name }},
6
5
 
@@ -1,6 +1,5 @@
1
1
  ---
2
2
  subject: '{{ title }} has started'
3
- from: 'admin@example.com'
4
3
  ---
5
4
  Hello {{ user.name }},
6
5
 
@@ -3,19 +3,9 @@ EffectivePolls.setup do |config|
3
3
  # Configure the Layout per controller, or all at once
4
4
  # config.layout = { application: 'application', admin: 'admin' }
5
5
 
6
- # Audience Scope Collection
7
- #
8
- # When creating a new poll, an Array of User scopes can be provided
9
- # The User model must respond to these
10
- #
11
- # config.audience_user_scopes = [:all, :registered]
12
- # config.audience_user_scopes = [['All Users', :all], ['Registered Users', :registered]]
13
- #
14
- config.audience_user_scopes = [['All Users', :all]]
15
-
16
6
  # Notifications Mailer Settings
17
7
  #
18
- # Schedule rake effective_polls:notify to run every 10 minutes
8
+ # Schedule rake effective_polls:send_notifications to run every 10 minutes
19
9
  # to send out email poll notifications
20
10
  #
21
11
  # Please see config/initializers/effective_resources.rb for default effective_* gem mailer settings
@@ -29,6 +19,7 @@ EffectivePolls.setup do |config|
29
19
  # config.deliver_method = nil # The deliver method, deliver_later or deliver_now
30
20
  # config.mailer_layout = nil # Default mailer layout
31
21
  # config.mailer_sender = nil # Default From value
22
+ # config.mailer_froms = nil # Default Froms collection
32
23
  # config.mailer_admin = nil # Default To value for Admin correspondence
33
24
 
34
25
  # Use effective email templates for event notifications
@@ -0,0 +1,14 @@
1
+ en:
2
+ effective_polls:
3
+ name: 'Elections and Polls'
4
+ acronym: 'Polls'
5
+
6
+ activerecord:
7
+ models:
8
+ effective/poll: 'Poll'
9
+ effective/poll_question: 'Poll Question'
10
+ effective/poll_question_option: 'Poll Question Option'
11
+ effective/poll_notification: 'Poll Notification'
12
+ effective/ballot: 'Ballot'
13
+ effective/ballot_response: 'Ballot Response'
14
+ effective/ballot_response_option: 'Ballot Response Option'
data/config/routes.rb CHANGED
@@ -5,17 +5,14 @@ end
5
5
  EffectivePolls::Engine.routes.draw do
6
6
  scope module: 'effective' do
7
7
  resources :polls, only: [:show] do
8
- resources :ballots, only: [:new, :show] do
8
+ resources :ballots, only: [:new, :show, :destroy] do
9
9
  resources :build, controller: :ballots, only: [:show, :update]
10
10
  end
11
11
  end
12
12
  end
13
13
 
14
14
  namespace :admin do
15
- resources :polls, except: [:show] do
16
- get :results, on: :member
17
- end
18
-
15
+ resources :polls
19
16
  resources :poll_notifications, except: [:show]
20
17
  resources :poll_questions, except: [:show]
21
18
  end
@@ -8,6 +8,8 @@ class CreateEffectivePolls < ActiveRecord::Migration[6.0]
8
8
  t.datetime :end_at
9
9
 
10
10
  t.string :audience
11
+
12
+ t.string :audience_class_name
11
13
  t.text :audience_scope
12
14
 
13
15
  t.datetime :updated_at
@@ -15,7 +17,7 @@ class CreateEffectivePolls < ActiveRecord::Migration[6.0]
15
17
  end
16
18
 
17
19
  create_table :poll_notifications do |t|
18
- t.integer :poll_id
20
+ t.references :poll, polymorphic: false
19
21
 
20
22
  t.string :category
21
23
  t.integer :reminder
@@ -32,7 +34,7 @@ class CreateEffectivePolls < ActiveRecord::Migration[6.0]
32
34
  end
33
35
 
34
36
  create_table :poll_questions do |t|
35
- t.integer :poll_id
37
+ t.references :poll, polymorphic: false
36
38
 
37
39
  t.string :title
38
40
  t.string :category
@@ -45,7 +47,7 @@ class CreateEffectivePolls < ActiveRecord::Migration[6.0]
45
47
  end
46
48
 
47
49
  create_table :poll_question_options do |t|
48
- t.integer :poll_question_id
50
+ t.references :poll_question, polymorphic: false
49
51
 
50
52
  t.string :title
51
53
  t.integer :position
@@ -55,8 +57,8 @@ class CreateEffectivePolls < ActiveRecord::Migration[6.0]
55
57
  end
56
58
 
57
59
  create_table :ballots do |t|
58
- t.integer :poll_id
59
- t.integer :user_id
60
+ t.references :poll, polymorphic: false
61
+ t.references :user, polymorphic: true
60
62
 
61
63
  t.string :token
62
64
  t.text :wizard_steps
@@ -67,9 +69,9 @@ class CreateEffectivePolls < ActiveRecord::Migration[6.0]
67
69
  end
68
70
 
69
71
  create_table :ballot_responses do |t|
70
- t.integer :ballot_id
71
- t.integer :poll_id
72
- t.integer :poll_question_id
72
+ t.references :ballot, polymorphic: false
73
+ t.references :poll, polymorphic: false
74
+ t.references :poll_question, polymorphic: false
73
75
 
74
76
  t.date :date
75
77
  t.string :email
@@ -82,8 +84,8 @@ class CreateEffectivePolls < ActiveRecord::Migration[6.0]
82
84
  end
83
85
 
84
86
  create_table :ballot_response_options do |t|
85
- t.integer :ballot_response_id
86
- t.integer :poll_question_option_id
87
+ t.references :ballot_response, polymorphic: false
88
+ t.references :poll_question_option, polymorphic: false
87
89
 
88
90
  t.datetime :updated_at
89
91
  t.datetime :created_at
data/db/seeds.rb CHANGED
@@ -9,7 +9,8 @@ def build_effective_poll
9
9
  title: 'Effective Poll',
10
10
  start_at: (Time.zone.now + 1.day).beginning_of_day,
11
11
  end_at: (Time.zone.now + 1.day).end_of_day,
12
- audience: 'All Users'
12
+ audience: 'All Users',
13
+ audience_class_name: 'User'
13
14
  )
14
15
 
15
16
  build_poll_question(poll, Effective::PollQuestion::CATEGORIES)
@@ -7,5 +7,12 @@ module EffectivePolls
7
7
  eval File.read("#{config.root}/config/effective_polls.rb")
8
8
  end
9
9
 
10
+ # Include effective_polls_user concern and allow any ActiveRecord object to call it
11
+ initializer 'effective_polls.active_record' do |app|
12
+ app.config.to_prepare do
13
+ ActiveRecord::Base.extend(EffectivePollsUser::Base)
14
+ end
15
+ end
16
+
10
17
  end
11
18
  end
@@ -1,3 +1,3 @@
1
1
  module EffectivePolls
2
- VERSION = '0.3.0'
2
+ VERSION = '0.4.0'
3
3
  end
@@ -7,10 +7,8 @@ module EffectivePolls
7
7
 
8
8
  def self.config_keys
9
9
  [
10
- :polls_table_name, :poll_notifications_table_name, :poll_questions_table_name, :poll_question_options_table_name,
11
- :ballots_table_name, :ballot_responses_table_name, :ballot_response_options_table_name,
12
- :layout, :audience_user_scopes,
13
- :mailer, :parent_mailer, :deliver_method, :mailer_layout, :mailer_sender, :mailer_admin, :mailer_subject, :use_effective_email_templates
10
+ :layout,
11
+ :mailer, :parent_mailer, :deliver_method, :mailer_layout, :mailer_sender, :mailer_froms, :mailer_admin, :mailer_subject, :use_effective_email_templates
14
12
  ]
15
13
  end
16
14
 
@@ -1,23 +1,34 @@
1
- # rake effective_polls:notify
1
+ # rake effective_polls:send_notifications
2
2
 
3
3
  namespace :effective_polls do
4
4
  desc 'Send email notifications for effective polls'
5
- task notify: :environment do
6
- poll_notifications = Effective::PollNotification.all.deep.notifiable
5
+ task send_notifications: :environment do
6
+ puts 'Sending notifications'
7
7
 
8
- poll_notifications.find_each do |notification|
9
- begin
10
- notified = notification.notify!
11
- puts "Sent #{notification.category} for #{notification.poll}" if notified
12
- rescue => e
13
- if defined?(ExceptionNotifier)
14
- ExceptionNotifier.notify_exception(e, data: { poll_notification_id: notification.id, poll_id: notification.poll_id })
15
- end
8
+ table = ActiveRecord::Base.connection.table_exists?(:poll_notifications)
9
+ blank_tenant = defined?(Tenant) && Tenant.current.blank?
16
10
 
17
- puts "Error with effective poll_notification #{notification.id}: #{e.errors.inspect}"
11
+ if table && !blank_tenant
12
+ poll_notifications = Effective::PollNotification.deep.notifiable
13
+
14
+ poll_notifications.find_each do |notification|
15
+ begin
16
+ notified = notification.notify!
17
+ puts "Sent #{notification.category} for #{notification.poll}" if notified
18
+ rescue StandardError => e
19
+ data = { poll_notification_id: notification.id, poll_id: notification.poll_id }
20
+ ExceptionNotifier.notify_exception(e, data: data) if defined?(ExceptionNotifier)
21
+ puts "Error with effective poll_notification #{notification.id}: #{e.errors.inspect}"
22
+ end
18
23
  end
19
24
  end
20
25
 
21
26
  puts 'All done'
22
27
  end
28
+
29
+ # Deprecated version
30
+ task notify: :environment do
31
+ Rake::Task['effective_polls:send_notifications'].invoke
32
+ end
33
+
23
34
  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.3.0
4
+ version: 0.4.0
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: 2023-10-05 00:00:00.000000000 Z
11
+ date: 2023-10-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -227,9 +227,10 @@ files:
227
227
  - app/datatables/admin/effective_poll_questions_datatable.rb
228
228
  - app/datatables/admin/effective_poll_results_datatable.rb
229
229
  - app/datatables/admin/effective_polls_datatable.rb
230
- - app/datatables/effective_polls_datatable.rb
230
+ - app/datatables/effective_polls_available_polls_datatable.rb
231
231
  - app/helpers/effective_polls_helper.rb
232
232
  - app/mailers/effective/polls_mailer.rb
233
+ - app/models/concerns/effective_polls_user.rb
233
234
  - app/models/effective/ballot.rb
234
235
  - app/models/effective/ballot_response.rb
235
236
  - app/models/effective/ballot_response_option.rb
@@ -247,7 +248,7 @@ files:
247
248
  - app/views/admin/polls/_form.html.haml
248
249
  - app/views/admin/polls/_form_content.html.haml
249
250
  - app/views/admin/polls/_form_poll.html.haml
250
- - app/views/admin/polls/results.html.haml
251
+ - app/views/admin/polls/_poll.html.haml
251
252
  - app/views/effective/ballot_responses/_ballot_response.html.haml
252
253
  - app/views/effective/ballot_responses/_fields.html.haml
253
254
  - app/views/effective/ballot_responses/fields/_choose_one.html.haml
@@ -277,6 +278,8 @@ files:
277
278
  - app/views/effective/ballot_responses/responses/_short_answer.html.haml
278
279
  - app/views/effective/ballot_responses/responses/_upload_file.html.haml
279
280
  - app/views/effective/ballots/_ballot.html.haml
281
+ - app/views/effective/ballots/_content.html.haml
282
+ - app/views/effective/ballots/_layout.html.haml
280
283
  - app/views/effective/ballots/complete.html.haml
281
284
  - app/views/effective/ballots/start.html.haml
282
285
  - app/views/effective/ballots/submit.html.haml
@@ -297,12 +300,14 @@ files:
297
300
  - app/views/effective/poll_results/results/_select_up_to_5.html.haml
298
301
  - app/views/effective/poll_results/results/_short_answer.html.haml
299
302
  - app/views/effective/poll_results/results/_upload_file.html.haml
303
+ - app/views/effective/polls/_dashboard.html.haml
300
304
  - app/views/effective/polls_mailer/poll_before_poll_ends.liquid
301
305
  - app/views/effective/polls_mailer/poll_reminder.liquid
302
306
  - app/views/effective/polls_mailer/poll_upcoming_reminder.liquid
303
307
  - app/views/effective/polls_mailer/poll_when_poll_ends.liquid
304
308
  - app/views/effective/polls_mailer/poll_when_poll_starts.liquid
305
309
  - config/effective_polls.rb
310
+ - config/locales/effective_polls.yml
306
311
  - config/routes.rb
307
312
  - db/migrate/101_create_effective_polls.rb
308
313
  - db/seeds.rb
@@ -1,6 +0,0 @@
1
- %h1= @page_title
2
-
3
- = render 'effective/poll_results/results', poll: @poll
4
-
5
- %h2 Raw Results
6
- = render_datatable(@datatable)