Enable blind voting
This commit is contained in:
parent
8388385b51
commit
59eeb7edbd
17 changed files with 391 additions and 108 deletions
|
|
@ -1,6 +1,14 @@
|
|||
// get current_date
|
||||
var today = new Date().toISOString().slice(0, 10);
|
||||
$(function () {
|
||||
$("input[id^='datetimepicker']").datetimepicker({
|
||||
pickTime: true,
|
||||
useCurrent: false,
|
||||
sideBySide: true,
|
||||
autoclose: true,
|
||||
format: 'YYYY-MM-DD HH:mm'
|
||||
});
|
||||
|
||||
$("#registration-arrival-datepicker").datetimepicker({
|
||||
pickTime: true,
|
||||
useCurrent: false,
|
||||
|
|
@ -12,7 +20,7 @@ $(function () {
|
|||
minDate : today,
|
||||
defaultDate : $("#registration-arrival-datepicker").attr('start_date'),
|
||||
});
|
||||
|
||||
|
||||
$("#registration-departure-datepicker").datetimepicker({
|
||||
pickTime: true,
|
||||
useCurrent: false,
|
||||
|
|
@ -23,7 +31,7 @@ $(function () {
|
|||
minDate : $("#registration-arrival-datepicker").attr('start_date'),
|
||||
defaultDate : $("#registration-arrival-datepicker").attr('end_date'),
|
||||
});
|
||||
|
||||
|
||||
$("#registration-arrival-datepicker").on("dp.change",function (e) {
|
||||
// departure_date > start_date,arrival_date
|
||||
if ((new Date(e.date).getTime()) > (new Date($("#registration-arrival-datepicker").attr('start_date')).getTime())){
|
||||
|
|
@ -52,7 +60,7 @@ $(function () {
|
|||
useCurrent: false,
|
||||
format: "YYYY-MM-DD",
|
||||
});
|
||||
|
||||
|
||||
// end_date_conference >= registration-period-Start_date >= Current_date
|
||||
// registration-period-Start_date <= registration-period-End_date <= End_date (of conference)
|
||||
$("#registration-period-start-datepicker").datetimepicker({
|
||||
|
|
@ -62,7 +70,7 @@ $(function () {
|
|||
minDate : today,
|
||||
maxDate : $("#registration-period-start-datepicker").attr('end_date'),
|
||||
});
|
||||
|
||||
|
||||
$("#registration-period-end-datepicker").datetimepicker({
|
||||
pickTime: false,
|
||||
useCurrent: false,
|
||||
|
|
@ -70,7 +78,7 @@ $(function () {
|
|||
minDate: today,
|
||||
maxDate : $("#registration-period-start-datepicker").attr('end_date'),
|
||||
});
|
||||
|
||||
|
||||
$("#conference-start-datepicker").on("dp.change",function (e) {
|
||||
$('#conference-end-datepicker').data("DateTimePicker").setMinDate(e.date);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ module Admin
|
|||
private
|
||||
|
||||
def program_params
|
||||
params.require(:program).permit(:rating, :schedule_public, :schedule_fluid, :languages)
|
||||
params.require(:program).permit(:rating, :schedule_public, :schedule_fluid, :languages, :blind_voting, :voting_start_date, :voting_end_date)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,4 +1,16 @@
|
|||
module ApplicationHelper
|
||||
##
|
||||
# Checks if the voting has already started, or if it has already ended
|
||||
#
|
||||
def voting_open_or_close(program)
|
||||
return if program.voting_period?
|
||||
if program.voting_start_date > Date.today
|
||||
return 'Voting period has not started yet!'
|
||||
else # voting_end_date > Date.today because voting_start_date < voting_end_date
|
||||
return 'Voting period is over!'
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Gets an EventType object, and returns its length in timestamp format (HH:MM)
|
||||
# ====Gets
|
||||
|
|
@ -9,6 +21,15 @@ module ApplicationHelper
|
|||
[length / 60, length % 60].map { |t| t.to_s.rjust(2, '0') }.join(':')
|
||||
end
|
||||
|
||||
##
|
||||
# Gets a datetime object
|
||||
# ====Returns
|
||||
# * +String+ -> formated datetime object
|
||||
def format_datetime(obj)
|
||||
return unless obj
|
||||
obj.strftime('%Y-%m-%d %H:%M')
|
||||
end
|
||||
|
||||
##
|
||||
# ====Returns
|
||||
# * +String+ -> number of registrations / max allowed registrations
|
||||
|
|
|
|||
|
|
@ -82,8 +82,24 @@ class Event < ActiveRecord::Base
|
|||
registrations.count < max_attendees
|
||||
end
|
||||
|
||||
def voted?(event, user)
|
||||
event.votes.where('user_id = ?', user).first
|
||||
##
|
||||
# Finds the rating of the user for the event
|
||||
# ====Returns
|
||||
# * +integer+ -> the rating of the user for the event
|
||||
def user_rating(user)
|
||||
(vote = votes.find_by(user: user)) ? vote.rating : 0
|
||||
end
|
||||
|
||||
##
|
||||
# Checks if the event has votes
|
||||
# If a user is provided, it checks if the event has votes by the user
|
||||
# ====Returns
|
||||
# * +true+ -> If the event has votes (optionally, by the user)
|
||||
# * +false+ -> If the event does not have any votes (optionally, by the user)
|
||||
def voted?(user=nil)
|
||||
return votes.where(user: user).any? if user
|
||||
|
||||
votes.any?
|
||||
end
|
||||
|
||||
def average_rating
|
||||
|
|
|
|||
|
|
@ -47,12 +47,58 @@ class Program < ActiveRecord::Base
|
|||
accepts_nested_attributes_for :difficulty_levels, allow_destroy: true
|
||||
|
||||
# validates :conference_id, presence: true, uniqueness: true
|
||||
validates :rating, numericality: { greater_than_or_equal_to: 0, less_than_or_equal_to: 10 }
|
||||
validates :rating, numericality: { greater_than_or_equal_to: 0, less_than_or_equal_to: 10, only_integer: true }
|
||||
validate :voting_start_date_before_end_date
|
||||
validate :voting_dates_exist
|
||||
|
||||
before_create :create_event_types
|
||||
before_create :create_difficulty_levels
|
||||
validate :check_languages_format
|
||||
|
||||
##
|
||||
# Checks if blind_voting is enabled and if voting period is over
|
||||
# ====Returns
|
||||
# * +true+ -> If we can show voting details
|
||||
# * +false+ -> If we cannot show voting details
|
||||
def show_voting?
|
||||
return true unless blind_voting
|
||||
|
||||
Date.today > voting_end_date
|
||||
end
|
||||
|
||||
##
|
||||
# Checks if we are still in voting period
|
||||
# ====Returns
|
||||
# * +true+ -> If the voting period is not over yet
|
||||
# * +false+ -> If the voting period is over
|
||||
def voting_period?
|
||||
return false unless voting_start_date && voting_end_date
|
||||
|
||||
(voting_start_date.to_datetime..voting_end_date.to_datetime).cover? Time.current
|
||||
end
|
||||
|
||||
##
|
||||
# Checks if both voting_start_date and voting_end_date are set
|
||||
# ====Returns
|
||||
# Errors when the condition is not true
|
||||
def voting_dates_exist
|
||||
errors.add(:voting_start_date, 'must be set, when blind voting is enabled') if blind_voting && !voting_start_date && !voting_end_date
|
||||
|
||||
errors.add(:voting_end_date, 'must be set, when blind voting is enabled') if blind_voting && !voting_start_date && !voting_end_date
|
||||
|
||||
errors.add(:voting_end_date, 'must be set, when voting_start_date is set') if voting_start_date && !voting_end_date
|
||||
|
||||
errors.add(:voting_start_date, 'must be set, when voting_end_date is set') if voting_end_date && !voting_start_date
|
||||
end
|
||||
|
||||
##
|
||||
# Checks if voting_start_date is before voting_end_date
|
||||
# ====Returns
|
||||
# Errors when the condition is not true
|
||||
def voting_start_date_before_end_date
|
||||
errors.add(:voting_start_date, 'must be before voting end date') if voting_start_date && voting_end_date && voting_start_date > voting_end_date
|
||||
end
|
||||
|
||||
##
|
||||
# Checcks if the program has rating enabled
|
||||
#
|
||||
|
|
|
|||
|
|
@ -122,10 +122,13 @@
|
|||
%td
|
||||
%b Submitter
|
||||
%td
|
||||
= link_to @event.submitter.name, admin_user_path(@event.submitter)
|
||||
(
|
||||
= link_to @event.submitter.email, "mailto: #{@event.submitter.email}"
|
||||
)
|
||||
- if @program.show_voting?
|
||||
= link_to @event.submitter.name, admin_user_path(@event.submitter)
|
||||
(
|
||||
= link_to @event.submitter.email, "mailto: #{@event.submitter.email}"
|
||||
)
|
||||
- else
|
||||
%i Hidden
|
||||
%tr
|
||||
%td
|
||||
%b Biography
|
||||
|
|
|
|||
|
|
@ -1,54 +1,64 @@
|
|||
%table.table#myrating
|
||||
- if @program.show_voting?
|
||||
%tr
|
||||
%td.col-md-2
|
||||
%b Rating
|
||||
%td
|
||||
- if @event.average_rating.to_f > 0
|
||||
#{@event.average_rating}/#{@program.rating}
|
||||
- else
|
||||
Rating: 0/#{@program.rating}
|
||||
|
||||
- @program.rating.times do |counter|
|
||||
- if @event.average_rating.to_f.round == counter+1
|
||||
= label_tag 'label_rating', '', class: 'avgrating', avgrate: true
|
||||
= javascript_tag "$('label[avgrate=true]').prevAll().andSelf().addClass('bright');"
|
||||
- else
|
||||
= label_tag 'label_rating', '', class: 'avgrating'
|
||||
%tr
|
||||
%td
|
||||
%b Voters
|
||||
%td
|
||||
= @event.voters.length
|
||||
- if @event.voters.length > 0
|
||||
(
|
||||
= @ratings.map {|x| "#{x.name}"}.join ', '
|
||||
)
|
||||
%tr
|
||||
%td.col-md-2
|
||||
%b Rating
|
||||
%td
|
||||
- if @event.average_rating.to_f > 0
|
||||
#{@event.average_rating}/#{@conference.program.rating}
|
||||
- else
|
||||
Rating: 0/#{@conference.program.rating}
|
||||
|
||||
- @conference.program.rating.times do |counter|
|
||||
- if @event.average_rating.to_f.round == counter+1
|
||||
= label_tag "label_rating", "", :class => "avgrating", :avgrate => true
|
||||
= javascript_tag "$('label[avgrate=true]').prevAll().andSelf().addClass('bright');"
|
||||
- else
|
||||
= label_tag "label_rating", "", :class => "avgrating"
|
||||
%tr
|
||||
%td
|
||||
%b Voters
|
||||
%td
|
||||
= @event.voters.length
|
||||
- if @event.voters.length > 0
|
||||
(
|
||||
= @ratings.map {|x| "#{x.name}"}.join ', '
|
||||
)
|
||||
%tr
|
||||
%td
|
||||
%b Your vote
|
||||
%td
|
||||
- @conference.program.rating.times do |counter|
|
||||
- voted = @event.voted?(@event, current_user)
|
||||
- if voted && voted.rating == counter+1
|
||||
= link_to "", vote_admin_conference_program_event_path(@conference.short_title, @event, :rating => counter+1), :remote => true, :id =>"label#{counter+1}", :class => "myrating", :voted => true
|
||||
- else
|
||||
= link_to "", vote_admin_conference_program_event_path(@conference.short_title, @event, :rating => counter+1), :remote => true, :id =>"label#{counter+1}", :class => "myrating"
|
||||
%br
|
||||
- if @program.voting_period?
|
||||
- @program.rating.times do |counter|
|
||||
- if @event.voted?(current_user) && @event.user_rating(current_user) == counter+1
|
||||
= link_to "", vote_admin_conference_program_event_path(@conference.short_title, @event, :rating => counter+1), :remote => true, :id =>"label#{counter+1}", :class => "myrating", :voted => true
|
||||
- else
|
||||
= link_to "", vote_admin_conference_program_event_path(@conference.short_title, @event, :rating => counter+1), :remote => true, :id =>"label#{counter+1}", :class => "myrating"
|
||||
%br
|
||||
- else
|
||||
- @conference.program.rating.times do |counter|
|
||||
- if @event.voted?(current_user) && @event.user_rating(current_user) == counter+1
|
||||
= label_tag "label#{counter+1}", '', class: 'othersrating', voted: true
|
||||
= javascript_tag "$('label[voted=true]').prevAll().andSelf().addClass('bright');"
|
||||
- else
|
||||
= label_tag "label#{counter+1}", '', class: 'othersrating'
|
||||
(#{voting_open_or_close(@program)})
|
||||
|
||||
- if @ratings.length > 0
|
||||
- @ratings.each do |rate|
|
||||
- unless rate.user_id == current_user.id
|
||||
%tr
|
||||
%td
|
||||
= rate.name
|
||||
%td
|
||||
- @conference.program.rating.times do |counter|
|
||||
- voted = @event.voted?(@event, rate.user)
|
||||
- if voted && voted.rating == counter+1
|
||||
= label_tag "label#{counter+1}", "", :class => "othersrating", :voted => true
|
||||
= javascript_tag "$('label[voted=true]').prevAll().andSelf().addClass('bright');"
|
||||
- else
|
||||
= label_tag "label#{counter+1}", "", :class => "othersrating"
|
||||
- if @program.show_voting?
|
||||
- if @ratings.length > 0
|
||||
- @ratings.each do |rate|
|
||||
- unless rate.user_id == current_user.id
|
||||
%tr
|
||||
%td
|
||||
= rate.name
|
||||
%td
|
||||
- @conference.program.rating.times do |counter|
|
||||
|
||||
- if @event.voted?(rate.user) && @event.user_rating(rate.user) == counter+1
|
||||
= label_tag "label#{counter+1}", "", :class => "othersrating", :voted => true
|
||||
= javascript_tag "$('label[voted=true]').prevAll().andSelf().addClass('bright');"
|
||||
- else
|
||||
= label_tag "label#{counter+1}", "", :class => "othersrating"
|
||||
:javascript
|
||||
$(function () {
|
||||
var checkedId = $("a[voted='true']").attr('id');
|
||||
|
|
|
|||
19
app/views/admin/events/_voting_index.html.haml
Normal file
19
app/views/admin/events/_voting_index.html.haml
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
- if @program.show_voting?
|
||||
#{event.average_rating}/#{@program.rating}
|
||||
%br
|
||||
#{pluralize(event.voters.length, 'voter')}
|
||||
%br
|
||||
- @program.rating.times do |counter|
|
||||
- if event.average_rating.to_f.round == counter+1
|
||||
= label_tag 'label_rating', '', class: 'avgrating', avgrate: true
|
||||
= javascript_tag "$('label[avgrate=true]').prevAll().andSelf().addClass('bright');"
|
||||
- else
|
||||
= label_tag 'label_rating', '', class: 'avgrating'
|
||||
%br
|
||||
|
||||
- if event.voted?(current_user)
|
||||
%span.label.label-success
|
||||
Your rating: #{ event.user_rating(current_user) }
|
||||
- else
|
||||
%span.label.label-danger
|
||||
Not rated
|
||||
|
|
@ -50,49 +50,34 @@
|
|||
%td
|
||||
= event.id
|
||||
%td
|
||||
=link_to event.title, admin_conference_program_event_path(@conference.short_title, event)
|
||||
= link_to event.title, admin_conference_program_event_path(@conference.short_title, event)
|
||||
|
||||
- if @program.rating_enabled?
|
||||
%td.col-md-1{'data-order' => "#{event.average_rating}"}
|
||||
- if event.average_rating.to_f > 0
|
||||
#{event.average_rating}/#{@program.rating}
|
||||
%br
|
||||
#{pluralize(event.voters.length, 'voter')}
|
||||
%br
|
||||
- @program.rating.times do |counter|
|
||||
- if event.average_rating.to_f.round == counter+1
|
||||
= label_tag "label_rating", "", :class => "avgrating", :avgrate => true
|
||||
= javascript_tag "$('label[avgrate=true]').prevAll().andSelf().addClass('bright');"
|
||||
- else
|
||||
= label_tag "label_rating", "", :class => "avgrating"
|
||||
%br
|
||||
- voted = event.voted?(event, current_user)
|
||||
- if voted
|
||||
%span.label.label-success
|
||||
Your rating: #{voted.rating}
|
||||
- else
|
||||
%span.label.label-danger
|
||||
Not rated
|
||||
- else
|
||||
0/#{@program.rating}
|
||||
%br
|
||||
= render partial: 'voting_index', locals: { event: event }
|
||||
|
||||
- if event.submitter && event.submitter.registrations && event.submitter.registrations.count < 1
|
||||
- bgcolor="#F7819F"
|
||||
- else
|
||||
- bgcolor=""
|
||||
%td{:style=>"background-color: #{bgcolor}"}
|
||||
- if !event.submitter.nil?
|
||||
=link_to event.submitter.name, admin_user_path(event.submitter)
|
||||
- if event.submitter.registrations.count < 1
|
||||
(Unregistered!)
|
||||
- if @program.show_voting?
|
||||
- if !event.submitter.nil?
|
||||
=link_to event.submitter.name, admin_user_path(event.submitter)
|
||||
- if event.submitter.registrations.count < 1
|
||||
(Unregistered!)
|
||||
- else
|
||||
Unknown submitter
|
||||
- else
|
||||
Unknown submitter
|
||||
%i Hidden
|
||||
%td
|
||||
- if speaker = event.speakers.first
|
||||
= link_to speaker.name, admin_user_path(speaker)
|
||||
- if @program.show_voting?
|
||||
- if speaker = event.speakers.first
|
||||
= link_to speaker.name, admin_user_path(speaker)
|
||||
- else
|
||||
Unknown speaker
|
||||
- else
|
||||
Unknown speaker
|
||||
%i Hidden
|
||||
|
||||
-if @program.languages.present?
|
||||
%td
|
||||
|
|
|
|||
|
|
@ -9,5 +9,8 @@
|
|||
= f.input :schedule_fluid, label: "Allow submitters to change their event after it is scheduled"
|
||||
= f.input :rating, hint: 'Enter the number of different rating levels you want to have for voting on proposals. Enter 0 if you do not want to vote on proposals.'
|
||||
= f.input :languages, hint: "Enter the languages allowed for events as values of #{link_to('ISO 639-1', 'http://www.loc.gov/standards/iso639-2/php/code_list.php', target: "_blank")} language codes separated with commas. The first language would be the default language. Leave it blank if you do not want to specify languages.".html_safe
|
||||
= f.input :blind_voting, hint: 'Enable this feature if you do not want to show voting results and voters prior to user submitting a vote. For the feature to work you need to set the voting dates below as well'
|
||||
= f.input :voting_start_date, as: :string, input_html: { id: 'datetimepicker-voting_start_date', readonly: true, value: (f.object.voting_start_date.to_formatted_s(:db_without_seconds) unless f.object.voting_start_date.nil?) }
|
||||
= f.input :voting_end_date, as: :string, input_html: { id: 'datetimepicker-voting_start_date', readonly: true, value: (f.object.voting_end_date.to_formatted_s(:db_without_seconds) unless f.object.voting_end_date.nil?) }
|
||||
%p.text-right
|
||||
= f.action :submit, as: :button, button_html: {class: 'btn btn-primary'}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
%h1 Program
|
||||
- if @program
|
||||
.row
|
||||
.col-md-8
|
||||
.col-md-12
|
||||
%dl.dl-horizontal
|
||||
- if @cfp
|
||||
%dt
|
||||
|
|
@ -49,11 +49,23 @@
|
|||
Yes
|
||||
- else
|
||||
No
|
||||
|
||||
%h3 Voting Options
|
||||
%hr
|
||||
%dt
|
||||
Rating Levels
|
||||
%dd#rating
|
||||
= @program.rating
|
||||
|
||||
%dt Blind Voting
|
||||
%dd#blind_voting
|
||||
= @program.blind_voting
|
||||
|
||||
%dt Voting Start Date
|
||||
%dd= format_datetime(@program.voting_start_date)
|
||||
|
||||
%dt Voting End Date
|
||||
%dd= format_datetime(@program.voting_end_date)
|
||||
|
||||
.row
|
||||
.col-md-12.text-right
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue