implement manual event management and support for multiple speakers per event

This commit is contained in:
Eugene Dubinin 2017-02-02 16:34:59 +02:00
parent 46a6a59622
commit 790e2fd3a2
24 changed files with 180 additions and 89 deletions

View file

@ -46,6 +46,7 @@
//= require unobtrusive_flash
//= require unobtrusive_flash_bootstrap
//= require countable
//= require selectize
$(document).ready(function() {
$('a[disabled=disabled]').click(function(event){

View file

@ -16,4 +16,6 @@
*= require bootstrap3-switch
*= require osem-payments
*= require osem-navbar
*= require selectize
*= require selectize.bootstrap3
*/

View file

@ -106,7 +106,11 @@ background-image: -webkit-gradient(
}
.speakerinfo {
margin-top: 20px;
margin-top: 40px;
}
.speakerbio {
margin-top: 10px;
}
.schedule-title, .schedule-subtitle, .schedule-speaker, .schedule-track {

View file

@ -5,7 +5,7 @@ module Admin
load_and_authorize_resource :event, through: :program
load_and_authorize_resource :events_registration, only: :toggle_attendance
before_action :get_event, except: [:index, :create]
before_action :get_event, except: [:index, :create, :new]
# FIXME: The timezome should only be applied on output, otherwise
# you get lost in timezone conversions...
@ -62,6 +62,7 @@ module Admin
@comments = @event.root_comments
@comment_count = @event.comment_threads.count
@user = @event.submitter
@users = User.all.order(:name)
@url = admin_conference_program_event_path(@conference.short_title, @event)
@languages = @program.languages_list
end
@ -79,6 +80,8 @@ module Admin
end
def update
@users = User.all.order(:name)
@languages = @program.languages_list
if @event.update_attributes(event_params)
if request.xhr?
@ -94,7 +97,26 @@ module Admin
end
end
def create; end
def create
@url = admin_conference_program_events_path(@conference.short_title, @event)
@users = User.all.order(:name)
@languages = @program.languages_list
@event.submitter = current_user
if @event.save
ahoy.track 'Event submission', title: 'New submission'
redirect_to admin_conference_program_events_path(@conference.short_title), notice: 'Event was successfully submitted.'
else
flash[:error] = "Could not submit proposal: #{@event.errors.full_messages.join(', ')}"
render action: 'new'
end
end
def new
@url = admin_conference_program_events_path(@conference.short_title, @event)
@languages = @program.languages_list
@users = User.all.order(:name)
end
def accept
send_mail = @event.program.conference.email_settings.send_on_accepted
@ -161,7 +183,8 @@ module Admin
# Set only in admin/events controller
:track_id, :state, :language, :is_highlight, :max_attendees,
# Not used anymore?
:proposal_additional_speakers, :user, :users_attributes)
:proposal_additional_speakers, :user, :users_attributes,
speaker_ids: [])
end
def comment_params

View file

@ -13,9 +13,8 @@ class ProposalsController < ApplicationController
end
def show
# FIXME: We should show more than the first speaker
@speaker = @event.speakers.first || @event.submitter
@event_schedule = @event.event_schedules.find_by(schedule_id: @program.selected_schedule_id)
@speakers_ordered = @event.speakers_ordered
end
def new
@ -26,6 +25,7 @@ class ProposalsController < ApplicationController
def edit
@url = conference_program_proposal_path(@conference.short_title, params[:id])
@users = User.all.order(:name)
@languages = @program.languages_list
end
@ -48,11 +48,8 @@ class ProposalsController < ApplicationController
# User which creates the proposal is both `submitter` and `speaker` of proposal
# by default.
# TODO: Allow submitter to add speakers to proposals
@event.event_users.new(user: current_user,
event_role: 'submitter')
@event.event_users.new(user: current_user,
event_role: 'speaker')
@event.speakers = [current_user]
@event.submitter = current_user
if @event.save
ahoy.track 'Event submission', title: 'New submission'
redirect_to conference_program_proposals_path(@conference.short_title), notice: 'Proposal was successfully submitted.'
@ -64,6 +61,7 @@ class ProposalsController < ApplicationController
def update
@url = conference_program_proposal_path(@conference.short_title, params[:id])
@users = User.all.order(:name)
if @event.update(event_params)
redirect_to conference_program_proposals_path(conference_id: @conference.short_title),
@ -147,7 +145,9 @@ class ProposalsController < ApplicationController
def event_params
params.require(:event).permit(:event_type_id, :track_id, :difficulty_level_id,
:title, :subtitle, :abstract, :description,
:require_registration, :max_attendees, :language)
:require_registration, :max_attendees, :language,
speaker_ids: []
)
end
def user_params

View file

@ -8,7 +8,13 @@ class Event < ActiveRecord::Base
has_many :event_users, dependent: :destroy
has_many :users, through: :event_users
has_many :speakers, through: :event_users, source: :user
has_many :speaker_event_users, -> { where(event_role: 'speaker') }, class_name: 'EventUser'
has_many :speakers, through: :speaker_event_users, source: :user
has_one :submitter_event_user, -> { where(event_role: 'submitter') }, class_name: 'EventUser'
has_one :submitter, through: :submitter_event_user, source: :user
has_many :votes, dependent: :destroy
has_many :voters, through: :votes, source: :user
has_many :commercials, as: :commercialable, dependent: :destroy
@ -23,6 +29,7 @@ class Event < ActiveRecord::Base
belongs_to :program
accepts_nested_attributes_for :event_users, allow_destroy: true
accepts_nested_attributes_for :speakers, allow_destroy: true
accepts_nested_attributes_for :users
before_create :generate_guid
@ -33,6 +40,7 @@ class Event < ActiveRecord::Base
validates :abstract, presence: true
validates :event_type, presence: true
validates :program, presence: true
validates :speakers, presence: true
validates :max_attendees, numericality: { only_integer: true, greater_than_or_equal_to: 1, allow_nil: true }
validate :max_attendees_no_more_than_room_size
@ -113,20 +121,16 @@ class Event < ActiveRecord::Base
@total_rating > 0 ? number_with_precision(@total_rating / @total.to_f, precision: 2, strip_insignificant_zeros: true) : 0
end
def submitter
result = event_users.where(event_role: 'submitter').first
if result.nil?
user = nil
# Perhaps the event_users haven't been saved, if this is a new proposal
event_users.each do |u|
if u.event_role == 'submitter'
user = u.user
end
end
user
else
result.user
# get event speakers with the event sumbmitter at the first position
# if the submitter is also a speaker for this event
def speakers_ordered
speakers_list = speakers.to_a
if speakers_list.reject! { |speaker| speaker == submitter }
speakers_list.unshift(submitter)
end
speakers_list
end
def transition_possible?(transition)

View file

@ -41,6 +41,7 @@ class User < ActiveRecord::Base
has_many :event_users, dependent: :destroy
has_many :events, -> { uniq }, through: :event_users
has_many :presented_events, -> { joins(:event_users).where(event_users: {event_role: 'speaker'}).uniq }, through: :event_users, source: :event
has_many :registrations, dependent: :destroy
has_many :events_registrations, through: :registrations
has_many :ticket_purchases, dependent: :destroy

View file

@ -0,0 +1,11 @@
.row
.col-md-12
.page-header
%h1
-if @event.new_record?
New
= @event.title
Event
.row
.col-md-12
= render 'proposals/proposal_form'

View file

@ -131,9 +131,26 @@
%i Hidden
%tr
%td
%b Biography
%b Speakers
%td
= markdown(@event.submitter.biography)
- if @program.show_voting?
- @event.speakers.each do |speaker|
%div
= link_to speaker.name, admin_user_path(speaker)
(
= link_to speaker.email, "mailto: #{speaker.email}"
)
- else
%i Hidden
%tr
%td
%b Biographies
%td
- @event.speakers.each do |speaker|
- unless speaker.biography.blank?
%b
= speaker.name
= markdown(speaker.biography)
%tr
%td
%b Submitted on

View file

@ -4,7 +4,9 @@
%h1
Events
= "(#{@events.length})" if @events.any?
.btn-group.pull-right
.pull-right
- if can? :create, Event
=link_to 'Add Event', new_admin_conference_program_event_path(@conference.short_title), class: 'button btn btn-default btn-info'
- if can? :read, Event
.btn-group
%button.btn.btn-default.dropdown-toggle{ 'data-toggle' => 'dropdown', type: 'button', class: 'btn btn-success' }
@ -54,8 +56,8 @@
%th
%b Submitter
%th
%b Speaker
- if @program.languages.present?
%b Speakers
-if @program.languages.present?
%th
%b Language
%th
@ -99,10 +101,9 @@
%i Hidden
%td
- if @program.show_voting?
- if speaker = event.speakers.first
= link_to speaker.name, admin_user_path(speaker)
- else
Unknown speaker
- event.speakers_ordered.each do |speaker|
.speaker
= link_to speaker.name, admin_user_path(speaker)
- else
%i Hidden

View file

@ -4,6 +4,10 @@
= f.input :subtitle, as: :string
= f.input :speakers, as: :select,
collection: options_for_select(@users.map {|user| ["#{user.name} (#{user.email})", user.id]}, @event.speakers.map(&:id)),
include_blank: false, label: 'Speakers', input_html: { class: 'select-help-toggle', multiple: 'true' }
- if @program.tracks.any?
= f.input :track_id, as: :select,
collection: @program.tracks.map {|track| ["#{track.name}", track.id] },
@ -60,4 +64,15 @@
%p.text-right
= f.submit 'Update Proposal', class: 'btn btn-success'
- if @event.new_record?
= f.submit 'Create Proposal', class: 'btn btn-success'
- else
= f.submit 'Update Proposal', class: 'btn btn-success'
:javascript
$(document).ready(function() {
$('#event_speaker_ids').selectize({
plugins: ['remove_button'],
maxItems: 5
} )
});

View file

@ -3,8 +3,9 @@
%meta{ property: "og:url", content: conference_program_proposal_url(@conference.short_title, @event) }
%meta{ property: "og:description", content: @event.abstract }
%meta{ property: "og:site_name", content: (ENV['OSEM_NAME'] || 'OSEM') }
%meta{ property: "og:image", content: @speaker.gravatar_url }
%meta{ property: "og:image:secure_url", content: @speaker.gravatar_url }
- if @speakers_ordered.any?
%meta{ property: "og:image", content: @speakers_ordered.first.gravatar_url }
%meta{ property: "og:image:secure_url", content: @speakers_ordered.first.gravatar_url }
.container
.row
@ -25,21 +26,25 @@
.row
.col-md-3
.speakerinfo
.col-md-12
= image_tag @speaker.gravatar_url(size: 200), class: 'img-responsive img-rounded'
.col-md-12
%h3
by
= link_to @speaker.name, user_path(@speaker.id)
= "(#{@speaker.email})" if @speaker.email_public
- if @speaker.affiliation?
%br
%span.muted
from
= @speaker.affiliation
-if @speaker.biography?
= markdown(@speaker.biography)
%h3
Presented by:
- @speakers_ordered.each do |speaker|
.speakerinfo
.row
.col-md-4
= image_tag speaker.gravatar_url(:size => 120), class: 'img-responsive img-rounded'
.col-md-8
%h4
= link_to speaker.name, user_path(speaker.id)
= "(#{speaker.email})"
- if speaker.affiliation?
.text-muted
from
= speaker.affiliation
-if speaker.biography?
.row.speakerbio
.col-md-12
= markdown(speaker.biography)
.col-md-9
.row
.col-md-12

View file

@ -1,9 +1,9 @@
.panel.panel-default.event-panel{ onClick: 'eventClicked(event, this);', "data-url" => "#{url_for(conference_program_proposal_path(@conference.short_title, event.id))}" }
.panel-body
- if speaker = event.speakers.first
= image_tag speaker.gravatar_url, class: "img-circle pull-right all-speaker-pic", |
alt: speaker.name, |
title: speaker.name |
- event.speakers_ordered.each do |speaker|
= image_tag speaker.gravatar_url, :class => "img-circle pull-right all-speaker-pic", |
:alt => speaker.name, |
:title => speaker.name |
%p
= canceled_replacement_event_label(event, event_schedule)

View file

@ -14,3 +14,9 @@
alt: speaker.name, |
title: speaker.name, |
style: "height: #{ speaker_height(@rooms) }px; width: #{ speaker_width(@rooms) }px;"
- event.speakers_ordered.each do |speaker|
= image_tag speaker.gravatar_url, :class => "img-circle pull-right speaker-pic", |
:alt => speaker.name, |
:title => speaker.name, |
:style => "height: #{ speaker_height(@rooms) }px; width: #{ speaker_width(@rooms) }px;"

View file

@ -11,11 +11,11 @@
= markdown(@user.biography)
.row
.col-md-12
- if @user.events.confirmed.any?
- if @user.presented_events.confirmed.any?
%h3
= "#{@user.name} presents #{pluralize(@user.events.confirmed.count, 'Event')}:"
= "#{@user.name} presents #{pluralize(@user.presented_events.confirmed.count, 'Event')}:"
%ul.list-unstyled
- @user.events.confirmed.each do |event|
- @user.presented_events.confirmed.each do |event|
%li
%h4
= link_to event.title, conference_program_proposal_path(event.program.conference.short_title, event.id)