effective_polls 0.8.1 → 0.9.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 (68) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/effective/ballots_controller.rb +3 -3
  3. data/app/datatables/admin/effective_polls_datatable.rb +1 -1
  4. data/app/models/effective/ballot.rb +2 -13
  5. data/app/models/effective/ballot_response.rb +2 -0
  6. data/app/models/effective/ballot_response_option.rb +2 -0
  7. data/app/models/effective/poll.rb +5 -15
  8. data/app/models/effective/poll_question.rb +2 -0
  9. data/app/models/effective/poll_question_option.rb +2 -0
  10. data/app/views/admin/polls/_form.html.haml +1 -1
  11. data/app/views/admin/polls/_poll.html.haml +2 -2
  12. data/app/views/effective/ballots/_ballot.html.haml +1 -21
  13. data/app/views/effective/ballots/vote.html.haml +1 -16
  14. data/app/views/effective/polls/_results.html.haml +26 -0
  15. data/config/routes.rb +0 -1
  16. data/db/migrate/101_create_effective_polls.rb +0 -52
  17. data/db/seeds.rb +13 -12
  18. data/lib/effective_polls/version.rb +1 -1
  19. data/lib/effective_polls.rb +1 -0
  20. metadata +17 -50
  21. data/app/controllers/admin/poll_questions_controller.rb +0 -13
  22. data/app/datatables/admin/effective_poll_questions_datatable.rb +0 -45
  23. data/app/datatables/admin/effective_poll_results_datatable.rb +0 -47
  24. data/app/views/admin/poll_questions/_form.html.haml +0 -132
  25. data/app/views/effective/ballot_responses/_ballot_response.html.haml +0 -2
  26. data/app/views/effective/ballot_responses/_fields.html.haml +0 -14
  27. data/app/views/effective/ballot_responses/fields/_choose_one.html.haml +0 -1
  28. data/app/views/effective/ballot_responses/fields/_date.html.haml +0 -2
  29. data/app/views/effective/ballot_responses/fields/_email.html.haml +0 -2
  30. data/app/views/effective/ballot_responses/fields/_long_answer.html.haml +0 -1
  31. data/app/views/effective/ballot_responses/fields/_number.html.haml +0 -2
  32. data/app/views/effective/ballot_responses/fields/_select_all_that_apply.html.haml +0 -1
  33. data/app/views/effective/ballot_responses/fields/_select_up_to_1.html.haml +0 -1
  34. data/app/views/effective/ballot_responses/fields/_select_up_to_2.html.haml +0 -1
  35. data/app/views/effective/ballot_responses/fields/_select_up_to_3.html.haml +0 -1
  36. data/app/views/effective/ballot_responses/fields/_select_up_to_4.html.haml +0 -1
  37. data/app/views/effective/ballot_responses/fields/_select_up_to_5.html.haml +0 -1
  38. data/app/views/effective/ballot_responses/fields/_short_answer.html.haml +0 -1
  39. data/app/views/effective/ballot_responses/fields/_upload_file.html.haml +0 -2
  40. data/app/views/effective/ballot_responses/responses/_choose_one.html.haml +0 -1
  41. data/app/views/effective/ballot_responses/responses/_date.html.haml +0 -1
  42. data/app/views/effective/ballot_responses/responses/_email.html.haml +0 -1
  43. data/app/views/effective/ballot_responses/responses/_long_answer.html.haml +0 -1
  44. data/app/views/effective/ballot_responses/responses/_number.html.haml +0 -1
  45. data/app/views/effective/ballot_responses/responses/_select_all_that_apply.html.haml +0 -5
  46. data/app/views/effective/ballot_responses/responses/_select_up_to_1.html.haml +0 -1
  47. data/app/views/effective/ballot_responses/responses/_select_up_to_2.html.haml +0 -5
  48. data/app/views/effective/ballot_responses/responses/_select_up_to_3.html.haml +0 -5
  49. data/app/views/effective/ballot_responses/responses/_select_up_to_4.html.haml +0 -5
  50. data/app/views/effective/ballot_responses/responses/_select_up_to_5.html.haml +0 -5
  51. data/app/views/effective/ballot_responses/responses/_short_answer.html.haml +0 -1
  52. data/app/views/effective/ballot_responses/responses/_upload_file.html.haml +0 -4
  53. data/app/views/effective/poll_results/_poll_result.html.haml +0 -2
  54. data/app/views/effective/poll_results/_results.html.haml +0 -57
  55. data/app/views/effective/poll_results/results/_choose_one.html.haml +0 -2
  56. data/app/views/effective/poll_results/results/_date.html.haml +0 -14
  57. data/app/views/effective/poll_results/results/_email.html.haml +0 -14
  58. data/app/views/effective/poll_results/results/_long_answer.html.haml +0 -2
  59. data/app/views/effective/poll_results/results/_number.html.haml +0 -14
  60. data/app/views/effective/poll_results/results/_poll_question_option.html.haml +0 -17
  61. data/app/views/effective/poll_results/results/_select_all_that_apply.html.haml +0 -2
  62. data/app/views/effective/poll_results/results/_select_up_to_1.html.haml +0 -2
  63. data/app/views/effective/poll_results/results/_select_up_to_2.html.haml +0 -2
  64. data/app/views/effective/poll_results/results/_select_up_to_3.html.haml +0 -2
  65. data/app/views/effective/poll_results/results/_select_up_to_4.html.haml +0 -2
  66. data/app/views/effective/poll_results/results/_select_up_to_5.html.haml +0 -2
  67. data/app/views/effective/poll_results/results/_short_answer.html.haml +0 -2
  68. data/app/views/effective/poll_results/results/_upload_file.html.haml +0 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 78cfacdfb3c91966205d106c8876f48cebc70ffe1a7b5c045e085f2cf1832506
4
- data.tar.gz: 7384c31ed9c721a568c5d2e514c21f114ee3055f70519a51ea7bd1600c497f4d
3
+ metadata.gz: 11143f2261f0f8612c941822e3bf9e1704a0947add8a5a6b3630d069e79f9c4e
4
+ data.tar.gz: e3e30bab0949f25f2a7e4abd91ed104bca8b81bee06ddb65ce143fae6cfcbbe4
5
5
  SHA512:
6
- metadata.gz: adff50a5d6a2ab422cdd86dba6a34d1d9dfcc8e7a8e15b9aafda92653f87e99e1c9d3cccf37e5fb7089168146ad5b158a96ea1493059570dbc1cd15aabe25d10
7
- data.tar.gz: 8189171d2185b2766e80ee85a34b13b0bf67c6c6b216098a98aac834c069eafdcb04a6ff705611af29538973e999c154ac718697066d69feb473e894bb3b7830
6
+ metadata.gz: 241e27e10d7d9679b110ef7e2074b783dce578082606518c5d07afad8b857e77c7106ba6d7b0d4bb1f46427f8defd184f75a25540cdca8886f5c30a758a02b61
7
+ data.tar.gz: 20785a03ed7d6c4b80dddce9d6c703676e03735fdd99bfbb78e60cd5587efbf2d9bebe24d23f21bbc6dfc2f1ddca389dc1ff0c117fb4c33ab61caf1185123615
@@ -54,10 +54,10 @@ module Effective
54
54
  when :start
55
55
  params.require(:effective_ballot).permit(:current_step)
56
56
  when :vote
57
- params.require(:effective_ballot).permit(:current_step, ballot_responses_attributes: [
58
- :id, :poll_id, :poll_question_id,
57
+ params.require(:effective_ballot).permit(:current_step, responses_attributes: [
58
+ :id, :questionable_type, :questionable_id, :question_id,
59
59
  :date, :email, :number, :long_answer, :short_answer, :upload_file, :_destroy,
60
- :poll_question_option_ids, poll_question_option_ids: []
60
+ :question_option_ids, question_option_ids: []
61
61
  ])
62
62
  when :submit
63
63
  params.require(:effective_ballot).permit(:current_step)
@@ -19,7 +19,7 @@ class Admin::EffectivePollsDatatable < Effective::Datatable
19
19
  col :audience
20
20
 
21
21
  col :poll_notifications
22
- col :poll_questions, visible: false
22
+ col :questions, visible: false
23
23
 
24
24
  col :hide_results, visible: false
25
25
  col :skip_logging, visible: false
@@ -9,10 +9,8 @@ module Effective
9
9
  # Effective namespace
10
10
  belongs_to :poll
11
11
 
12
- has_many :ballot_responses, dependent: :destroy
13
- accepts_nested_attributes_for :ballot_responses, allow_destroy: true
14
-
15
12
  acts_as_tokened
13
+ acts_as_responsable
16
14
 
17
15
  log_changes(to: :poll) if respond_to?(:log_changes)
18
16
 
@@ -37,7 +35,7 @@ module Effective
37
35
  timestamps
38
36
  end
39
37
 
40
- scope :deep, -> { includes(:poll, :user, ballot_responses: [:poll, :poll_question, :poll_question_options]) }
38
+ scope :deep, -> { includes(:poll, :user, responses: [:questionable, :question, :question_options]) }
41
39
  scope :sorted, -> { order(:id) }
42
40
 
43
41
  scope :in_progress, -> { where(completed_at: nil) }
@@ -53,9 +51,6 @@ module Effective
53
51
  scope: :poll_id, allow_blank: true, message: 'ballot already exists for this poll'
54
52
  }
55
53
 
56
- # I seem to need this even tho I accept_nested_attributes
57
- validates :ballot_responses, associated: true
58
-
59
54
  def to_s
60
55
  model_name.human
61
56
  end
@@ -66,12 +61,6 @@ module Effective
66
61
  true
67
62
  end
68
63
 
69
- # Find or build
70
- def ballot_response(poll_question)
71
- ballot_response = ballot_responses.find { |br| br.poll_question_id == poll_question.id }
72
- ballot_response ||= ballot_responses.build(poll: poll_question.poll, poll_question: poll_question)
73
- end
74
-
75
64
  # This is the review step where they click Submit Ballot
76
65
  def submit!
77
66
  wizard_steps[:complete] ||= Time.zone.now
@@ -1,3 +1,5 @@
1
+ # TO BE DELETED
2
+
1
3
  module Effective
2
4
  class BallotResponse < ActiveRecord::Base
3
5
  belongs_to :ballot
@@ -1,3 +1,5 @@
1
+ # TO BE DELETED
2
+
1
3
  module Effective
2
4
  class BallotResponseOption < ActiveRecord::Base
3
5
  belongs_to :ballot_response
@@ -1,19 +1,15 @@
1
1
  module Effective
2
2
  class Poll < ActiveRecord::Base
3
3
  acts_as_tokened
4
+ acts_as_questionable
4
5
 
5
6
  has_many :poll_notifications, -> { order(:id) }, inverse_of: :poll, dependent: :destroy
6
7
  accepts_nested_attributes_for :poll_notifications, allow_destroy: true
7
8
 
8
- has_many :poll_questions, -> { order(:position) }, inverse_of: :poll, dependent: :destroy
9
- accepts_nested_attributes_for :poll_questions, allow_destroy: true
10
-
11
9
  has_many :ballots
12
- has_many :ballot_responses
13
10
 
14
11
  # For the poll_results screens
15
12
  has_many :completed_ballots, -> { Effective::Ballot.completed }, class_name: 'Effective::Ballot'
16
- has_many :completed_ballot_responses, -> { where(ballot: Effective::Ballot.completed) }, class_name: 'Effective::BallotResponse'
17
13
 
18
14
  has_many_rich_texts
19
15
  # rich_text_all_steps_content
@@ -23,7 +19,7 @@ module Effective
23
19
  # rich_text_complete_content
24
20
 
25
21
  if respond_to?(:log_changes)
26
- log_changes(except: [:ballots, :ballot_responses, :completed_ballots, :completed_ballot_responses])
22
+ log_changes(except: [:ballots, :responses])
27
23
  end
28
24
 
29
25
  AUDIENCES = ['All Users', 'Individual Users', 'Selected Users']
@@ -53,11 +49,11 @@ module Effective
53
49
  serialize :audience_scope, Array
54
50
  end
55
51
 
56
- scope :deep, -> { includes(:poll_notifications, poll_questions: :poll_question_options) }
52
+ scope :deep, -> { includes(:poll_notifications, questions: :question_options) }
57
53
 
58
54
  scope :deep_results, -> {
59
- includes(poll_questions: :poll_question_options)
60
- .includes(ballots: [ballot_responses: [:poll, :poll_question, :poll_question_options]])
55
+ includes(questions: :question_options)
56
+ .includes(ballots: [responses: [:questionable, :question, :question_options]])
61
57
  }
62
58
 
63
59
  scope :sorted, -> { order(:start_at) }
@@ -150,11 +146,5 @@ module Effective
150
146
  Array(self[:audience_scope]) - [nil, '']
151
147
  end
152
148
 
153
- # Returns all completed_ballot_responses
154
- def poll_results(poll_question: nil)
155
- return completed_ballot_responses if poll_question.nil?
156
- completed_ballot_responses.select { |br| br.poll_question_id == poll_question.id }
157
- end
158
-
159
149
  end
160
150
  end
@@ -1,3 +1,5 @@
1
+ # TO BE DELETED
2
+
1
3
  module Effective
2
4
  class PollQuestion < ActiveRecord::Base
3
5
  belongs_to :poll
@@ -1,3 +1,5 @@
1
+ # TO BE DELETED
2
+
1
3
  module Effective
2
4
  class PollQuestionOption < ActiveRecord::Base
3
5
  belongs_to :poll_question
@@ -7,7 +7,7 @@
7
7
  = render 'admin/polls/form_content', poll: poll
8
8
 
9
9
  = tab 'Questions' do
10
- - datatable = Admin::EffectivePollQuestionsDatatable.new(poll: poll)
10
+ - datatable = Admin::EffectiveQuestionsDatatable.new(questionable: poll)
11
11
  = render_datatable(datatable, inline: true, simple: true)
12
12
 
13
13
  = tab 'Notifications' do
@@ -1,8 +1,8 @@
1
- = render 'effective/poll_results/results', poll: @poll
1
+ = render 'effective/polls/results', poll: @poll
2
2
 
3
3
  = card('Raw Data') do
4
4
  - if poll.hide_results? && !poll.ended?
5
5
  %p The raw data for this poll will be displayed once it has ended.
6
6
  - else
7
- - datatable = Admin::EffectivePollResultsDatatable.new(poll: @poll)
7
+ - datatable = Admin::EffectiveQuestionableResultsDatatable.new(questionable: @poll)
8
8
  = render_datatable(datatable)
@@ -1,22 +1,2 @@
1
1
  .effective-ballot
2
- %table.table.table-hover
3
- %thead
4
- %tr
5
- %th Question
6
- %th Response
7
-
8
- %tbody
9
- - ballot.poll.poll_questions.top_level.deep.each do |poll_question|
10
- - ballot_response = ballot.ballot_response(poll_question)
11
-
12
- %tr
13
- %td= poll_question
14
- %td= render(ballot_response)
15
-
16
- - poll_question.follow_up_poll_questions.deep.each do |follow_up_poll_question|
17
- - ballot_response = ballot.ballot_response(follow_up_poll_question)
18
-
19
- - if ballot_response.persisted?
20
- %tr
21
- %td= follow_up_poll_question
22
- %td= render(ballot_response)
2
+ = render('effective/responsable/results', responsable: resource, questionable: resource.poll)
@@ -5,21 +5,6 @@
5
5
  = effective_form_with(model: resource, url: wizard_path(step), method: :put) do |f|
6
6
  = f.hidden_field :current_step
7
7
 
8
- - resource.poll.poll_questions.top_level.deep.each do |poll_question|
9
- - ballot_response = resource.ballot_response(poll_question)
10
-
11
- = f.fields_for :ballot_responses, ballot_response do |fbr|
12
- = render('/effective/ballot_responses/fields', f: fbr, poll_question: poll_question)
13
-
14
- - poll_question.follow_up_poll_questions.each do |follow_up|
15
- - ballot_response = resource.ballot_response(follow_up)
16
-
17
- = fbr.show_if(poll_question.show_if_attribute, follow_up.show_if_value) do
18
- = f.fields_for :ballot_responses, ballot_response do |fbr|
19
- = render('/effective/ballot_responses/fields', f: fbr, poll_question: follow_up)
20
-
21
- = fbr.hide_if(poll_question.show_if_attribute, follow_up.show_if_value) do
22
- = f.fields_for :ballot_responses, ballot_response do |fbr|
23
- = fbr.hidden_field :_destroy, value: true
8
+ = render('effective/responsable/fields', f: f, responsable: resource, questionable: resource.poll)
24
9
 
25
10
  = f.submit 'Save and Continue', center: true
@@ -0,0 +1,26 @@
1
+ .card.mb-3
2
+ .card-body
3
+ %h5.card-title Results
4
+
5
+ %p #{poll} was available from #{poll.available_date}.
6
+
7
+ %p
8
+ %strong
9
+ = pluralize(poll.completed_ballots.count, 'user')
10
+ completed
11
+ ballots
12
+
13
+ - users_count = (poll.users.count rescue nil)
14
+ - if users_count.present?
15
+ from an audience of
16
+ = succeed('.') do
17
+ %strong= pluralize(users_count, 'total user')
18
+
19
+ .card.mb-3
20
+ .card-body
21
+ %h5.card-title Question Results
22
+
23
+ - if poll.hide_results? && !poll.ended?
24
+ %p The results of this poll will be displayed once it has ended.
25
+ - else
26
+ = render 'effective/questionable/results', questionable: poll
data/config/routes.rb CHANGED
@@ -14,7 +14,6 @@ EffectivePolls::Engine.routes.draw do
14
14
  namespace :admin do
15
15
  resources :polls
16
16
  resources :poll_notifications, except: [:show]
17
- resources :poll_questions, except: [:show]
18
17
  end
19
18
 
20
19
  end
@@ -40,35 +40,6 @@ class CreateEffectivePolls < ActiveRecord::Migration[6.0]
40
40
  t.datetime :created_at
41
41
  end
42
42
 
43
- create_table :poll_questions do |t|
44
- t.references :poll, polymorphic: false
45
-
46
- t.string :title
47
- t.string :category
48
- t.boolean :required, default: true
49
-
50
- t.integer :position
51
-
52
- t.boolean :follow_up, default: false
53
- t.string :follow_up_value
54
-
55
- t.integer :poll_question_id
56
- t.integer :poll_question_option_id
57
-
58
- t.datetime :updated_at
59
- t.datetime :created_at
60
- end
61
-
62
- create_table :poll_question_options do |t|
63
- t.references :poll_question, polymorphic: false
64
-
65
- t.string :title
66
- t.integer :position
67
-
68
- t.datetime :updated_at
69
- t.datetime :created_at
70
- end
71
-
72
43
  create_table :ballots do |t|
73
44
  t.references :poll, polymorphic: false
74
45
  t.references :user, polymorphic: true
@@ -81,28 +52,5 @@ class CreateEffectivePolls < ActiveRecord::Migration[6.0]
81
52
  t.datetime :created_at
82
53
  end
83
54
 
84
- create_table :ballot_responses do |t|
85
- t.references :ballot, polymorphic: false
86
- t.references :poll, polymorphic: false
87
- t.references :poll_question, polymorphic: false
88
-
89
- t.date :date
90
- t.string :email
91
- t.integer :number
92
- t.text :long_answer
93
- t.text :short_answer
94
-
95
- t.datetime :updated_at
96
- t.datetime :created_at
97
- end
98
-
99
- create_table :ballot_response_options do |t|
100
- t.references :ballot_response, polymorphic: false
101
- t.references :poll_question_option, polymorphic: false
102
-
103
- t.datetime :updated_at
104
- t.datetime :created_at
105
- end
106
-
107
55
  end
108
56
  end
data/db/seeds.rb CHANGED
@@ -1,9 +1,5 @@
1
1
  puts "Running effective_polls seeds"
2
2
 
3
- Effective::Poll.all.each { |poll| poll.destroy! }
4
-
5
- Effective::Ballot.delete_all
6
-
7
3
  def build_effective_poll
8
4
  poll = Effective::Poll.new(
9
5
  title: 'Effective Poll',
@@ -13,20 +9,25 @@ def build_effective_poll
13
9
  audience_class_name: 'User'
14
10
  )
15
11
 
16
- build_poll_question(poll, Effective::PollQuestion::CATEGORIES)
12
+ build_question(poll, Effective::Question::CATEGORIES)
17
13
 
18
14
  poll.save!
19
15
  poll
20
16
  end
21
17
 
22
- def build_poll_question(poll, category)
18
+ def build_question(poll, category)
23
19
  questions = Array(category).map.with_index do |category, index|
24
- question = poll.poll_questions.build(title: "#{category} Question ##{index+1}", category: category)
25
-
26
- if question.poll_question_option?
27
- question.poll_question_options.build(title: 'Option A')
28
- question.poll_question_options.build(title: 'Option B')
29
- question.poll_question_options.build(title: 'Option C')
20
+ question = Effective::Question.new(
21
+ questionable: poll,
22
+ title: "#{category} Question ##{index+1}",
23
+ category: category
24
+ )
25
+ poll.questions << question
26
+
27
+ if question.question_option?
28
+ question.question_options.build(title: 'Option A')
29
+ question.question_options.build(title: 'Option B')
30
+ question.question_options.build(title: 'Option C')
30
31
  end
31
32
  end
32
33
 
@@ -1,3 +1,3 @@
1
1
  module EffectivePolls
2
- VERSION = '0.8.1'
2
+ VERSION = '0.9.0'
3
3
  end
@@ -1,5 +1,6 @@
1
1
  require 'effective_resources'
2
2
  require 'effective_datatables'
3
+ require 'effective_questions'
3
4
  require 'effective_polls/engine'
4
5
  require 'effective_polls/version'
5
6
 
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.8.1
4
+ version: 0.9.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: 2025-04-25 00:00:00.000000000 Z
11
+ date: 2026-01-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: effective_questions
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: wicked
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -219,13 +233,10 @@ files:
219
233
  - app/assets/config/effective_polls_manifest.js
220
234
  - app/assets/stylesheets/effective_polls.scss
221
235
  - app/controllers/admin/poll_notifications_controller.rb
222
- - app/controllers/admin/poll_questions_controller.rb
223
236
  - app/controllers/admin/polls_controller.rb
224
237
  - app/controllers/effective/ballots_controller.rb
225
238
  - app/controllers/effective/polls_controller.rb
226
239
  - app/datatables/admin/effective_poll_notifications_datatable.rb
227
- - app/datatables/admin/effective_poll_questions_datatable.rb
228
- - app/datatables/admin/effective_poll_results_datatable.rb
229
240
  - app/datatables/admin/effective_polls_datatable.rb
230
241
  - app/datatables/effective_polls_available_polls_datatable.rb
231
242
  - app/helpers/effective_polls_helper.rb
@@ -244,39 +255,10 @@ files:
244
255
  - app/views/admin/poll_notifications/_form_poll_upcoming_reminder.html.haml
245
256
  - app/views/admin/poll_notifications/_form_poll_when_poll_ends.html.haml
246
257
  - app/views/admin/poll_notifications/_form_poll_when_poll_starts.html.haml
247
- - app/views/admin/poll_questions/_form.html.haml
248
258
  - app/views/admin/polls/_form.html.haml
249
259
  - app/views/admin/polls/_form_content.html.haml
250
260
  - app/views/admin/polls/_form_poll.html.haml
251
261
  - app/views/admin/polls/_poll.html.haml
252
- - app/views/effective/ballot_responses/_ballot_response.html.haml
253
- - app/views/effective/ballot_responses/_fields.html.haml
254
- - app/views/effective/ballot_responses/fields/_choose_one.html.haml
255
- - app/views/effective/ballot_responses/fields/_date.html.haml
256
- - app/views/effective/ballot_responses/fields/_email.html.haml
257
- - app/views/effective/ballot_responses/fields/_long_answer.html.haml
258
- - app/views/effective/ballot_responses/fields/_number.html.haml
259
- - app/views/effective/ballot_responses/fields/_select_all_that_apply.html.haml
260
- - app/views/effective/ballot_responses/fields/_select_up_to_1.html.haml
261
- - app/views/effective/ballot_responses/fields/_select_up_to_2.html.haml
262
- - app/views/effective/ballot_responses/fields/_select_up_to_3.html.haml
263
- - app/views/effective/ballot_responses/fields/_select_up_to_4.html.haml
264
- - app/views/effective/ballot_responses/fields/_select_up_to_5.html.haml
265
- - app/views/effective/ballot_responses/fields/_short_answer.html.haml
266
- - app/views/effective/ballot_responses/fields/_upload_file.html.haml
267
- - app/views/effective/ballot_responses/responses/_choose_one.html.haml
268
- - app/views/effective/ballot_responses/responses/_date.html.haml
269
- - app/views/effective/ballot_responses/responses/_email.html.haml
270
- - app/views/effective/ballot_responses/responses/_long_answer.html.haml
271
- - app/views/effective/ballot_responses/responses/_number.html.haml
272
- - app/views/effective/ballot_responses/responses/_select_all_that_apply.html.haml
273
- - app/views/effective/ballot_responses/responses/_select_up_to_1.html.haml
274
- - app/views/effective/ballot_responses/responses/_select_up_to_2.html.haml
275
- - app/views/effective/ballot_responses/responses/_select_up_to_3.html.haml
276
- - app/views/effective/ballot_responses/responses/_select_up_to_4.html.haml
277
- - app/views/effective/ballot_responses/responses/_select_up_to_5.html.haml
278
- - app/views/effective/ballot_responses/responses/_short_answer.html.haml
279
- - app/views/effective/ballot_responses/responses/_upload_file.html.haml
280
262
  - app/views/effective/ballots/_ballot.html.haml
281
263
  - app/views/effective/ballots/_content.html.haml
282
264
  - app/views/effective/ballots/_layout.html.haml
@@ -284,23 +266,8 @@ files:
284
266
  - app/views/effective/ballots/start.html.haml
285
267
  - app/views/effective/ballots/submit.html.haml
286
268
  - app/views/effective/ballots/vote.html.haml
287
- - app/views/effective/poll_results/_poll_result.html.haml
288
- - app/views/effective/poll_results/_results.html.haml
289
- - app/views/effective/poll_results/results/_choose_one.html.haml
290
- - app/views/effective/poll_results/results/_date.html.haml
291
- - app/views/effective/poll_results/results/_email.html.haml
292
- - app/views/effective/poll_results/results/_long_answer.html.haml
293
- - app/views/effective/poll_results/results/_number.html.haml
294
- - app/views/effective/poll_results/results/_poll_question_option.html.haml
295
- - app/views/effective/poll_results/results/_select_all_that_apply.html.haml
296
- - app/views/effective/poll_results/results/_select_up_to_1.html.haml
297
- - app/views/effective/poll_results/results/_select_up_to_2.html.haml
298
- - app/views/effective/poll_results/results/_select_up_to_3.html.haml
299
- - app/views/effective/poll_results/results/_select_up_to_4.html.haml
300
- - app/views/effective/poll_results/results/_select_up_to_5.html.haml
301
- - app/views/effective/poll_results/results/_short_answer.html.haml
302
- - app/views/effective/poll_results/results/_upload_file.html.haml
303
269
  - app/views/effective/polls/_dashboard.html.haml
270
+ - app/views/effective/polls/_results.html.haml
304
271
  - app/views/effective/polls_mailer/poll_before_poll_ends.liquid
305
272
  - app/views/effective/polls_mailer/poll_reminder.liquid
306
273
  - app/views/effective/polls_mailer/poll_upcoming_reminder.liquid
@@ -1,13 +0,0 @@
1
- module Admin
2
- class PollQuestionsController < ApplicationController
3
- before_action(:authenticate_user!) if defined?(Devise)
4
- before_action { EffectiveResources.authorize!(self, :admin, :effective_polls) }
5
-
6
- include Effective::CrudController
7
-
8
- def permitted_params
9
- params.require(:effective_poll_question).permit!
10
- end
11
-
12
- end
13
- end
@@ -1,45 +0,0 @@
1
- class Admin::EffectivePollQuestionsDatatable < Effective::Datatable
2
- datatable do
3
- reorder :position
4
-
5
- col :updated_at, visible: false
6
- col :created_at, visible: false
7
- col :id, visible: false
8
-
9
- if attributes[:follow_up]
10
- col :show_if_value_to_s, label: 'When answered with'
11
- else
12
- col :poll
13
- end
14
-
15
- col :position, visible: false do |poll_question|
16
- poll_question.position.to_i + 1
17
- end
18
-
19
- col :title
20
- col :body, as: :text, visible: !attributes[:follow_up]
21
- col :required
22
-
23
- col :category, label: 'Type'
24
- col :poll_question_options, label: 'Options'
25
-
26
- unless attributes[:follow_up]
27
- col :follow_up_poll_questions, action: false, label: 'Follow up questions'
28
- end
29
-
30
- actions_col
31
- end
32
-
33
- collection do
34
- scope = Effective::PollQuestion.all.deep
35
-
36
- if attributes[:follow_up]
37
- scope = scope.where(follow_up: true, poll_question_id: attributes[:poll_question_id])
38
- else
39
- scope = scope.where(poll_question_id: nil)
40
- end
41
-
42
- scope
43
- end
44
-
45
- end
@@ -1,47 +0,0 @@
1
- class Admin::EffectivePollResultsDatatable < Effective::Datatable
2
- datatable do
3
- col :ballot, search: poll.completed_ballots.order(:token).pluck(:token)
4
-
5
- col :position, visible: false
6
- col :category, search: Effective::PollQuestion::CATEGORIES, visible: false
7
-
8
- col :question, search: poll.poll_questions.pluck(:title).sort
9
- col :responses
10
- end
11
-
12
- collection do
13
- ballot_responses = Effective::BallotResponse.completed.deep.where(poll: poll, poll_question: poll.poll_questions)
14
-
15
- ballot_responses.flat_map do |br|
16
- rows = if br.poll_question.poll_question_option?
17
- br.poll_question_options.map do |response|
18
- [
19
- br.ballot.token,
20
- br.poll_question.position,
21
- br.poll_question.category,
22
- br.poll_question.to_s,
23
- response.to_s
24
- ]
25
- end
26
- elsif br.response.present?
27
- [
28
- [
29
- br.ballot.token,
30
- br.poll_question.position,
31
- br.poll_question.category,
32
- br.poll_question.to_s,
33
- br.response.to_s
34
- ]
35
- ]
36
- else
37
- []
38
- end
39
- end
40
-
41
- end
42
-
43
- def poll
44
- @poll ||= Effective::Poll.deep_results.where(id: attributes[:poll_id]).first!
45
- end
46
-
47
- end
@@ -1,132 +0,0 @@
1
- = effective_form_with(model: [:admin, poll_question], engine: true) do |f|
2
- - if inline_datatable?
3
- = f.hidden_field :poll_id
4
- - else
5
- = f.select :poll_id, Effective::Poll.all
6
-
7
- -# Follow up
8
- - if inline_datatable? && (original = f.object.poll_question).present?
9
- = f.hidden_field :follow_up, value: true
10
- = f.hidden_field :poll_question_id
11
-
12
- .mb-3.card
13
- .card-body
14
- %h5 Follow up Question
15
- %p.text-muted This question will only appear when they answer the above question with the following value:
16
-
17
- - if original.poll_question_option?
18
- = f.select :poll_question_option_id, original.poll_question_options, label: 'Answer required to display this question'
19
- - else
20
- = f.text_field :follow_up_value, label: 'Answer required to display this question', required: true, hint: 'Enter the exact answer value that should trigger this question to appear'
21
-
22
- = f.text_field :title, label: 'Question Title'
23
-
24
- - if defined?(EffectiveArticleEditor)
25
- = f.article_editor :body, label: 'Body (optional)'
26
- - else
27
- = f.rich_text_area :body, label: 'Body (optional)'
28
-
29
- = f.check_box :required, hint: 'A response to this question will be required'
30
- = f.select :category, Effective::PollQuestion::CATEGORIES
31
-
32
- = f.show_if :category, 'Choose one' do
33
- .mt-3.card
34
- .card-body
35
- %h5 Choose one
36
- %p Display radio buttons to select one option
37
-
38
- = f.show_if :category, 'Select all that apply' do
39
- .card
40
- .card-body
41
- %h5 Select all that apply
42
- %p Display checkboxes to select all options that apply
43
-
44
- = f.show_if :category, 'Select up to 1' do
45
- .card
46
- .card-body
47
- %h5 Select up to 1 (one)
48
- %p Display checkboxes to select up to 1 option
49
-
50
- = f.show_if :category, 'Select up to 2' do
51
- .card
52
- .card-body
53
- %h5 Select up to 2 (two)
54
- %p Display checkboxes to select up to 2 options
55
-
56
- = f.show_if :category, 'Select up to 3' do
57
- .card
58
- .card-body
59
- %h5 Select up to 3 (three)
60
- %p Display checkboxes to select up to 3 options
61
-
62
- = f.show_if :category, 'Select up to 4' do
63
- .card
64
- .card-body
65
- %h5 Select up to 4 (four)
66
- %p Display checkboxes to select up to 4 options
67
-
68
- = f.show_if :category, 'Select up to 5' do
69
- .card
70
- .card-body
71
- %h5 Select up to 5 (five)
72
- %p Display checkboxes to select up to 5 options
73
-
74
- = f.show_if :category, 'Short Answer' do
75
- .card
76
- .card-body
77
- %h5 Short Answer
78
- %p Display a text field to enter a short text answer
79
-
80
- = f.show_if :category, 'Long Answer' do
81
- .card
82
- .card-body
83
- %h5 Long Answer
84
- %p Display a textarea to enter a long text answer
85
-
86
- = f.show_if :category, 'Date' do
87
- .card
88
- .card-body
89
- %h5 Date
90
- %p Display a date field to enter a date
91
-
92
- = f.show_if :category, 'Email' do
93
- .card
94
- .card-body
95
- %h5 Email
96
- %p Display an email field to enter an email
97
-
98
- = f.show_if :category, 'Number' do
99
- .card
100
- .card-body
101
- %h5 Number
102
- %p Display a number field to enter an integer number
103
-
104
- = f.show_if :category, 'Upload File' do
105
- .card
106
- .card-body
107
- %h5 Upload File
108
- %p Display a file field to upload a file
109
-
110
- = f.show_if_any :category, Effective::PollQuestion::WITH_OPTIONS_CATEGORIES do
111
- .mt-3.card
112
- .card-body
113
- %h5 Options
114
- %p Display the following options:
115
-
116
- = f.has_many :poll_question_options, class: 'tight' do |fa|
117
- = fa.text_field :title, label: false
118
-
119
- = effective_submit(f)
120
-
121
- - unless poll_question.follow_up?
122
- %h2 Follow up questions
123
-
124
- - if Effective::PollQuestion::UNSUPPORTED_FOLLOW_UP_QUESTION_CATEGORIES.include?(poll_question.category)
125
- %p.text-muted
126
- %em Follow up questions are not supported for the #{poll_question.category} question category
127
- - elsif poll_question.new_record?
128
- %p.text-muted
129
- %em Please save this question to add follow up questions
130
- - else
131
- %p Display follow up question(s) based on the answer to this question:
132
- = render_inline_datatable Admin::EffectivePollQuestionsDatatable.new(follow_up: true, poll_question: poll_question)
@@ -1,2 +0,0 @@
1
- - partial = 'effective/ballot_responses/responses/' + ballot_response.category_partial
2
- = render(partial, ballot_response: ballot_response)
@@ -1,14 +0,0 @@
1
- .row
2
- .col
3
- %h3= poll_question
4
- %p.text-muted.mb-2= poll_question.category
5
-
6
- - if poll_question.body.present?
7
- .mb-3= poll_question.body
8
-
9
- = f.hidden_field :poll_id
10
- = f.hidden_field :poll_question_id
11
-
12
- - ballot_response = f.object
13
- - partial = 'effective/ballot_responses/fields/' + poll_question.category_partial
14
- = render(partial, f: f, ballot_response: ballot_response, poll_question: poll_question)
@@ -1 +0,0 @@
1
- = f.radios :poll_question_option_ids, poll_question.poll_question_options, label: false, required: poll_question.required?
@@ -1,2 +0,0 @@
1
- .row
2
- .col-sm-6= f.date_field :date, label: false, required: poll_question.required?
@@ -1,2 +0,0 @@
1
- .row
2
- .col-sm-6= f.email_field :email, label: false, required: poll_question.required?
@@ -1 +0,0 @@
1
- = f.text_area :long_answer, label: false, required: poll_question.required?
@@ -1,2 +0,0 @@
1
- .row
2
- .col-sm-6= f.number_field :number, label: false, required: poll_question.required?
@@ -1 +0,0 @@
1
- = f.checks :poll_question_option_ids, poll_question.poll_question_options, label: false, required: poll_question.required?
@@ -1 +0,0 @@
1
- = f.checks :poll_question_option_ids, poll_question.poll_question_options, label: false, actions: false, required: poll_question.required?
@@ -1 +0,0 @@
1
- = f.checks :poll_question_option_ids, poll_question.poll_question_options, label: false, actions: false, required: poll_question.required?
@@ -1 +0,0 @@
1
- = f.checks :poll_question_option_ids, poll_question.poll_question_options, label: false, actions: false, required: poll_question.required?
@@ -1 +0,0 @@
1
- = f.checks :poll_question_option_ids, poll_question.poll_question_options, label: false, actions: false, required: poll_question.required?
@@ -1 +0,0 @@
1
- = f.checks :poll_question_option_ids, poll_question.poll_question_options, label: false, actions: false, required: poll_question.required?
@@ -1 +0,0 @@
1
- = f.text_field :short_answer, label: false, required: poll_question.required?
@@ -1,2 +0,0 @@
1
- - # Always required false here because we'll handle the logic in the ballot_response model
2
- = f.file_field :upload_file, label: false, required: false
@@ -1 +0,0 @@
1
- = ballot_response.response.presence || '-'
@@ -1 +0,0 @@
1
- = ballot_response.response&.strftime('%F') || '-'
@@ -1 +0,0 @@
1
- = ballot_response.response.present? ? mail_to(ballot_response.response) : '-'
@@ -1 +0,0 @@
1
- = ballot_response.response.presence || '-'
@@ -1 +0,0 @@
1
- = ballot_response.response.presence || '-'
@@ -1,5 +0,0 @@
1
- - ballot_response.response.each do |poll_question_option|
2
- %div= poll_question_option.title
3
-
4
- - if ballot_response.response.blank?
5
- = '-'
@@ -1 +0,0 @@
1
- = ballot_response.response&.title || '-'
@@ -1,5 +0,0 @@
1
- - ballot_response.response.each do |poll_question_option|
2
- %div= poll_question_option.title
3
-
4
- - if ballot_response.response.blank?
5
- = '-'
@@ -1,5 +0,0 @@
1
- - ballot_response.response.each do |poll_question_option|
2
- %div= poll_question_option.title
3
-
4
- - if ballot_response.response.blank?
5
- = '-'
@@ -1,5 +0,0 @@
1
- - ballot_response.response.each do |poll_question_option|
2
- %div= poll_question_option.title
3
-
4
- - if ballot_response.response.blank?
5
- = '-'
@@ -1,5 +0,0 @@
1
- - ballot_response.response.each do |poll_question_option|
2
- %div= poll_question_option.title
3
-
4
- - if ballot_response.response.blank?
5
- = '-'
@@ -1 +0,0 @@
1
- = ballot_response.response.presence || '-'
@@ -1,4 +0,0 @@
1
- - if ballot_response.response&.attached?
2
- = link_to(ballot_response.response.filename, url_for(ballot_response.response), target: '_blank')
3
- - else
4
- = '-'
@@ -1,2 +0,0 @@
1
- - partial = 'effective/poll_results/results/' + poll_question.category_partial
2
- = render(partial, poll_question: poll_question, ballot_responses: ballot_responses)
@@ -1,57 +0,0 @@
1
- .card.mb-3
2
- .card-body
3
- %h5.card-title Results
4
-
5
- %p #{poll} was available from #{poll.available_date}.
6
-
7
- %p
8
- %strong
9
- = pluralize(poll.completed_ballots.count, 'user')
10
- completed
11
- ballots
12
-
13
- - users_count = (poll.users.count rescue nil)
14
- - if users_count.present?
15
- from an audience of
16
- = succeed('.') do
17
- %strong= pluralize(users_count, 'total user')
18
-
19
- .card.mb-3
20
- .card-body
21
- %h5.card-title Question Results
22
-
23
- - if poll.hide_results? && !poll.ended?
24
- %p The results of this poll will be displayed once it has ended.
25
- - else
26
- .effective-ballot
27
- %table.table.table-hover
28
- %thead
29
- %tr
30
- %th Question
31
- %th Results
32
-
33
- %tbody
34
- - ballots = poll.ballots
35
-
36
- - poll.poll_questions.top_level.each_with_index do |poll_question, index|
37
- - ballot_responses = poll.poll_results(poll_question: poll_question)
38
-
39
- %tr
40
- %td
41
- #{index + 1}. #{poll_question}
42
- %br
43
- %small.text-muted= poll_question.category
44
-
45
- %td= render('effective/poll_results/poll_result', poll_question: poll_question, ballot_responses: ballot_responses)
46
-
47
- - poll_question.follow_up_poll_questions.each_with_index do |follow_up_poll_question, index|
48
- - ballot_responses = poll.poll_results(poll_question: follow_up_poll_question)
49
-
50
- %tr
51
- %td
52
- .ml-4
53
- #{('a'.ord + index).chr}. #{follow_up_poll_question}
54
- %br
55
- %small.text-muted= follow_up_poll_question.category
56
-
57
- %td= render('effective/poll_results/poll_result', poll_question: follow_up_poll_question, ballot_responses: ballot_responses)
@@ -1,2 +0,0 @@
1
- - partial = 'effective/poll_results/results/poll_question_option'
2
- = render(partial, poll_question: poll_question, ballot_responses: ballot_responses)
@@ -1,14 +0,0 @@
1
- - sorted = ballot_responses.sort { |a, b| (a.date || Time.zone.now.end_of_year) <=> (b.date || Time.zone.now.end_of_year) }
2
-
3
- - sorted.group_by { |br| br.response }.each do |response, responses|
4
- - count = responses.length
5
- - total = ballot_responses.length
6
- - percent = (total.zero? ? 0 : ((count * 100.0) / total).round)
7
-
8
- .poll-result-option
9
- .d-flex
10
- .mr-auto= response.blank? ? 'None of the Above' : response.strftime('%F')
11
- .text-muted #{count} (#{percent}%)
12
-
13
- .progress.mb-3
14
- .progress-bar{role: 'progressbar', 'aria-valuenow': count, 'aria-valuemin': 0, 'aria-valuemax': total, style: "width: #{percent}%"}
@@ -1,14 +0,0 @@
1
- - sorted = ballot_responses.sort { |a, b| (a.email || '') <=> (b.email || '') }
2
-
3
- - sorted.group_by { |br| br.response }.each do |response, responses|
4
- - count = responses.length
5
- - total = ballot_responses.length
6
- - percent = (total.zero? ? 0 : ((count * 100.0) / total).round)
7
-
8
- .poll-result-option
9
- .d-flex
10
- .mr-auto= response.blank? ? 'None of the Above' : response
11
- .text-muted #{count} (#{percent}%)
12
-
13
- .progress.mb-3
14
- .progress-bar{role: 'progressbar', 'aria-valuenow': count, 'aria-valuemin': 0, 'aria-valuemax': total, style: "width: #{percent}%"}
@@ -1,2 +0,0 @@
1
- - ballot_responses.select { |br| br.long_answer.present? }.each do |ballot_response|
2
- .poll-result-long-answer= ballot_response.response
@@ -1,14 +0,0 @@
1
- - sorted = ballot_responses.sort { |a, b| (a.number || 999999999) <=> (b.number || 999999999) }
2
-
3
- - sorted.group_by { |br| br.response }.each do |response, responses|
4
- - count = responses.length
5
- - total = ballot_responses.length
6
- - percent = (total.zero? ? 0 : ((count * 100.0) / total).round)
7
-
8
- .poll-result-option
9
- .d-flex
10
- .mr-auto= response.blank? ? 'None of the Above' : response
11
- .text-muted #{count} (#{percent}%)
12
-
13
- .progress.mb-3
14
- .progress-bar{role: 'progressbar', 'aria-valuenow': count, 'aria-valuemin': 0, 'aria-valuemax': total, style: "width: #{percent}%"}
@@ -1,17 +0,0 @@
1
- - (poll_question.poll_question_options + [nil]).each do |poll_question_option|
2
- - responses = ballot_responses.select { |br| br.response.blank? } if poll_question_option.blank?
3
- - responses ||= ballot_responses.select { |br| Array(br.response).include?(poll_question_option) }
4
-
5
- - count = responses.length
6
- - total = ballot_responses.length
7
- - percent = (total.zero? ? 0 : ((count * 100.0) / total).round)
8
-
9
- - next if poll_question_option.blank? && count == 0
10
-
11
- .poll-result-option
12
- .d-flex
13
- .mr-auto= poll_question_option.blank? ? 'None of the Above' : poll_question_option
14
- .text-muted #{count} (#{percent}%)
15
-
16
- .progress.mb-3
17
- .progress-bar{role: 'progressbar', 'aria-valuenow': count, 'aria-valuemin': 0, 'aria-valuemax': total, style: "width: #{percent}%"}
@@ -1,2 +0,0 @@
1
- - partial = 'effective/poll_results/results/poll_question_option'
2
- = render(partial, poll_question: poll_question, ballot_responses: ballot_responses)
@@ -1,2 +0,0 @@
1
- - partial = 'effective/poll_results/results/poll_question_option'
2
- = render(partial, poll_question: poll_question, ballot_responses: ballot_responses)
@@ -1,2 +0,0 @@
1
- - partial = 'effective/poll_results/results/poll_question_option'
2
- = render(partial, poll_question: poll_question, ballot_responses: ballot_responses)
@@ -1,2 +0,0 @@
1
- - partial = 'effective/poll_results/results/poll_question_option'
2
- = render(partial, poll_question: poll_question, ballot_responses: ballot_responses)
@@ -1,2 +0,0 @@
1
- - partial = 'effective/poll_results/results/poll_question_option'
2
- = render(partial, poll_question: poll_question, ballot_responses: ballot_responses)
@@ -1,2 +0,0 @@
1
- - partial = 'effective/poll_results/results/poll_question_option'
2
- = render(partial, poll_question: poll_question, ballot_responses: ballot_responses)
@@ -1,2 +0,0 @@
1
- - ballot_responses.select { |br| br.short_answer.present? }.each do |ballot_response|
2
- .poll-result-short-answer= ballot_response.response
@@ -1,3 +0,0 @@
1
- - ballot_responses.select { |br| br.response&.attached? }.each do |ballot_response|
2
- .poll-result-upload-file
3
- = link_to(ballot_response.response.filename, url_for(ballot_response.response), target: '_blank')