effective_polls 0.2.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/MIT-LICENSE +1 -1
- data/README.md +2 -2
- data/Rakefile +5 -19
- data/app/controllers/admin/polls_controller.rb +1 -7
- data/app/controllers/effective/ballots_controller.rb +4 -1
- data/app/datatables/admin/effective_poll_notifications_datatable.rb +4 -1
- data/app/datatables/admin/effective_poll_results_datatable.rb +1 -4
- data/app/datatables/admin/effective_polls_datatable.rb +1 -0
- data/app/datatables/{effective_polls_datatable.rb → effective_polls_available_polls_datatable.rb} +6 -4
- data/app/helpers/effective_polls_helper.rb +17 -13
- data/app/mailers/effective/polls_mailer.rb +3 -1
- data/app/models/concerns/effective_polls_user.rb +67 -0
- data/app/models/effective/ballot.rb +11 -2
- data/app/models/effective/ballot_response.rb +1 -1
- data/app/models/effective/poll.rb +39 -26
- data/app/models/effective/poll_notification.rb +2 -2
- data/app/models/effective/poll_question.rb +1 -1
- data/app/models/effective/poll_question_option.rb +1 -1
- data/app/views/admin/poll_notifications/_form.html.haml +3 -5
- data/app/views/admin/poll_questions/_form.html.haml +12 -5
- data/app/views/admin/polls/_form.html.haml +10 -5
- data/app/views/admin/polls/_form_content.html.haml +16 -20
- data/app/views/admin/polls/_form_poll.html.haml +16 -7
- data/app/views/admin/polls/_poll.html.haml +5 -0
- data/app/views/effective/ballots/_content.html.haml +10 -0
- data/app/views/effective/ballots/_layout.html.haml +3 -0
- data/app/views/effective/ballots/complete.html.haml +13 -8
- data/app/views/effective/ballots/start.html.haml +29 -12
- data/app/views/effective/ballots/submit.html.haml +10 -13
- data/app/views/effective/ballots/vote.html.haml +10 -15
- data/app/views/effective/poll_results/_results.html.haml +2 -2
- data/app/views/effective/polls/_dashboard.html.haml +25 -0
- data/app/views/effective/polls_mailer/poll_before_poll_ends.liquid +0 -1
- data/app/views/effective/polls_mailer/poll_reminder.liquid +0 -1
- data/app/views/effective/polls_mailer/poll_upcoming_reminder.liquid +0 -1
- data/app/views/effective/polls_mailer/poll_when_poll_ends.liquid +0 -1
- data/app/views/effective/polls_mailer/poll_when_poll_starts.liquid +0 -1
- data/config/effective_polls.rb +2 -19
- data/config/locales/effective_polls.yml +14 -0
- data/config/routes.rb +2 -5
- data/db/migrate/{01_create_effective_polls.rb.erb → 101_create_effective_polls.rb} +19 -17
- data/db/seeds.rb +36 -0
- data/lib/effective_polls/engine.rb +7 -0
- data/lib/effective_polls/version.rb +1 -1
- data/lib/effective_polls.rb +2 -4
- data/lib/generators/effective_polls/install_generator.rb +1 -9
- data/lib/tasks/effective_polls_tasks.rake +23 -12
- metadata +144 -12
- 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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 637320f25a72489ada773806629e70590bb5c8435e871a6de40497e2eb6300ed
|
4
|
+
data.tar.gz: e797d1afdad6be66099b291ec7a809cbb65ef32d7963ca04f03d3ac3d91fe2a9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7317013d4063bdd11eaf4a72b6d5ca964c7acb2c35ac29653e9c7043c4e4c40de4e1b4b55079ed023b758f08982a51ca17926e37c5abafbca2462cf0b4a9e657
|
7
|
+
data.tar.gz: d3fe9a3b04a9ca98c5a27fa956fb82d536db6b9662b6d61a0e8fd954f603673384f6d70c3ec33e51fabde548063b126892508e858be72e616d2c9ff30318e732
|
data/MIT-LICENSE
CHANGED
data/README.md
CHANGED
@@ -10,7 +10,7 @@ Works with action_text for content bodies, and active_storage for file uploads.
|
|
10
10
|
|
11
11
|
## Getting Started
|
12
12
|
|
13
|
-
This requires Rails 6
|
13
|
+
This requires Rails 6 and Twitter Bootstrap 4 and just works with Devise.
|
14
14
|
|
15
15
|
Please first install the [effective_datatables](https://github.com/code-and-effect/effective_datatables) gem.
|
16
16
|
|
@@ -19,7 +19,7 @@ Please download and install the [Twitter Bootstrap4](http://getbootstrap.com)
|
|
19
19
|
Add to your Gemfile:
|
20
20
|
|
21
21
|
```ruby
|
22
|
-
gem 'haml
|
22
|
+
gem 'haml'
|
23
23
|
gem 'effective_polls'
|
24
24
|
```
|
25
25
|
|
data/Rakefile
CHANGED
@@ -1,27 +1,13 @@
|
|
1
|
-
|
2
|
-
require 'bundler/setup'
|
3
|
-
rescue LoadError
|
4
|
-
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
-
end
|
6
|
-
|
7
|
-
require 'rdoc/task'
|
8
|
-
|
9
|
-
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
-
rdoc.rdoc_dir = 'rdoc'
|
11
|
-
rdoc.title = 'EffectivePolls'
|
12
|
-
rdoc.options << '--line-numbers'
|
13
|
-
rdoc.rdoc_files.include('README.md')
|
14
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
-
end
|
1
|
+
require "bundler/setup"
|
16
2
|
|
17
3
|
APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
|
18
|
-
load
|
4
|
+
load "rails/tasks/engine.rake"
|
19
5
|
|
20
|
-
load
|
6
|
+
load "rails/tasks/statistics.rake"
|
21
7
|
|
22
|
-
require
|
8
|
+
require "bundler/gem_tasks"
|
23
9
|
|
24
|
-
require
|
10
|
+
require "rake/testtask"
|
25
11
|
|
26
12
|
Rake::TestTask.new(:test) do |t|
|
27
13
|
t.libs << 'test'
|
@@ -5,13 +5,7 @@ module Admin
|
|
5
5
|
|
6
6
|
include Effective::CrudController
|
7
7
|
|
8
|
-
|
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
|
-
|
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
|
|
@@ -41,10 +41,7 @@ class Admin::EffectivePollResultsDatatable < Effective::Datatable
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def poll
|
44
|
-
@poll ||=
|
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
|
data/app/datatables/{effective_polls_datatable.rb → effective_polls_available_polls_datatable.rb}
RENAMED
@@ -1,13 +1,14 @@
|
|
1
|
+
# Dashboard available polls
|
1
2
|
# Displays available polls that the current_user may complete
|
2
3
|
|
3
|
-
class
|
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
|
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
|
-
|
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
|
-
|
6
|
-
|
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
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
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
|
19
|
-
|
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
|
-
|
60
|
+
model_name.human
|
52
61
|
end
|
53
62
|
|
54
63
|
# Find or build
|
@@ -1,10 +1,6 @@
|
|
1
1
|
module Effective
|
2
2
|
class Poll < ActiveRecord::Base
|
3
|
-
|
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
|
-
|
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
|
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
|
40
|
-
|
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 ||
|
75
|
+
title.presence || model_name.human
|
79
76
|
end
|
80
77
|
|
81
78
|
def available_for?(user)
|
82
|
-
raise('expected
|
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
|
-
|
95
|
+
klass.try(:unarchived) || klass.all
|
90
96
|
when 'Individual Users'
|
91
|
-
|
97
|
+
(klass.try(:unarchived) || klass.all).where(id: audience_scope)
|
92
98
|
when 'Selected Users'
|
93
|
-
collection =
|
94
|
-
|
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
|
-
'
|
84
|
+
[category.presence, subject.presence].compact.join(' - ') || model_name.human
|
85
85
|
end
|
86
86
|
|
87
87
|
def email_template
|
@@ -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.
|
5
|
+
= f.select :poll_id, Effective::Poll.all
|
6
6
|
|
7
7
|
= f.text_field :title, label: 'Question Title'
|
8
|
-
|
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
|
17
|
-
%p Display
|
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(
|
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, '
|
16
|
+
= pluralize(poll.users.count, 'user')
|
17
17
|
in the audience.
|
18
18
|
|
19
|
-
|
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?(:
|
27
|
+
- if poll.respond_to?(:logs_datatable)
|
23
28
|
= tab 'Logs' do
|
24
|
-
= render_datatable(poll.
|
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
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
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
|
-
|
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
|
-
.
|
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
|
-
.
|
18
|
-
.
|
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
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
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
|