Merge pull request #52 from snap-cloud/add-volunteers
Allow scheduling volunteers for sessions.
This commit is contained in:
commit
859a47b79b
12 changed files with 110 additions and 31 deletions
|
|
@ -12,6 +12,7 @@ class ProposalsController < ApplicationController
|
||||||
@event = @program.events.new
|
@event = @program.events.new
|
||||||
@event.event_users.new(user: current_user, event_role: 'submitter')
|
@event.event_users.new(user: current_user, event_role: 'submitter')
|
||||||
@events = current_user.proposals(@conference)
|
@events = current_user.proposals(@conference)
|
||||||
|
@volunteer_events = current_user.volunteer_duties(@conference)
|
||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
|
|
@ -171,7 +172,7 @@ class ProposalsController < ApplicationController
|
||||||
params.require(:event).permit(:event_type_id, :track_id, :difficulty_level_id,
|
params.require(:event).permit(:event_type_id, :track_id, :difficulty_level_id,
|
||||||
:title, :subtitle, :abstract, :description,
|
:title, :subtitle, :abstract, :description,
|
||||||
:require_registration, :max_attendees, :language,
|
:require_registration, :max_attendees, :language,
|
||||||
speaker_ids: []
|
speaker_ids: [], volunteer_ids: []
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -123,6 +123,16 @@ module ApplicationHelper
|
||||||
user_selector_input(:speakers, form, '', true)
|
user_selector_input(:speakers, form, '', true)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def volunteer_links(event)
|
||||||
|
safe_join(event.volunteers.map do |volunteer|
|
||||||
|
link_to(volunteer.name, admin_user_path(volunteer))
|
||||||
|
end, ',')
|
||||||
|
end
|
||||||
|
|
||||||
|
def volunteer_selector_input(form)
|
||||||
|
user_selector_input(:volunteers, form, '', true)
|
||||||
|
end
|
||||||
|
|
||||||
def responsibles_selector_input(form)
|
def responsibles_selector_input(form)
|
||||||
user_selector_input(
|
user_selector_input(
|
||||||
:responsibles,
|
:responsibles,
|
||||||
|
|
@ -144,7 +154,7 @@ module ApplicationHelper
|
||||||
(form.object.send(field)&.map(&:id) || form.object.send(field)&.id)
|
(form.object.send(field)&.map(&:id) || form.object.send(field)&.id)
|
||||||
),
|
),
|
||||||
input_html: {
|
input_html: {
|
||||||
class: 'select-help-toggle',
|
class: 'select-help-toggle js-userSelector',
|
||||||
multiple: multiple,
|
multiple: multiple,
|
||||||
placeholder: (multiple ? 'Select users...' : 'Select a user...')
|
placeholder: (multiple ? 'Select users...' : 'Select a user...')
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,9 @@ class Event < ApplicationRecord
|
||||||
has_one :submitter_event_user, -> { where(event_role: 'submitter') }, class_name: 'EventUser'
|
has_one :submitter_event_user, -> { where(event_role: 'submitter') }, class_name: 'EventUser'
|
||||||
has_one :submitter, through: :submitter_event_user, source: :user
|
has_one :submitter, through: :submitter_event_user, source: :user
|
||||||
|
|
||||||
|
has_many :volunteer_event_users, -> { where(event_role: 'volunteer') }, class_name: 'EventUser'
|
||||||
|
has_many :volunteers, through: :volunteer_event_users, source: :user
|
||||||
|
|
||||||
has_many :votes, dependent: :destroy
|
has_many :votes, dependent: :destroy
|
||||||
has_many :voters, through: :votes, source: :user
|
has_many :voters, through: :votes, source: :user
|
||||||
has_many :commercials, as: :commercialable, dependent: :destroy
|
has_many :commercials, as: :commercialable, dependent: :destroy
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class EventUser < ApplicationRecord
|
class EventUser < ApplicationRecord
|
||||||
# TODO: Do we need these roles?
|
ROLES = [%w[Speaker speaker], %w[Submitter submitter], %w[Moderator moderator],
|
||||||
ROLES = [%w[Speaker speaker], %w[Submitter submitter], %w[Moderator moderator]]
|
%w[Volunteer volunteer]]
|
||||||
|
|
||||||
belongs_to :event, touch: true
|
belongs_to :event, touch: true
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
|
|
|
||||||
|
|
@ -256,6 +256,12 @@ class User < ApplicationRecord
|
||||||
result
|
result
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# TODO: Use a real authorization in the right place....
|
||||||
|
def manages_volunteers?(conference)
|
||||||
|
organizer_roles = get_roles['organizer']
|
||||||
|
organizer_roles&.include?(conference.short_title) # TODO or Volunteer Coorinator.
|
||||||
|
end
|
||||||
|
|
||||||
def registered
|
def registered
|
||||||
registrations = self.registrations
|
registrations = self.registrations
|
||||||
if registrations.count == 0
|
if registrations.count == 0
|
||||||
|
|
@ -290,6 +296,11 @@ class User < ApplicationRecord
|
||||||
proposals(conference).count
|
proposals(conference).count
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def volunteer_duties(conference)
|
||||||
|
events.where(program_id: conference.program.id, 'event_users.event_role': 'volunteer')
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
def self.empty?
|
def self.empty?
|
||||||
User.count == 1 && User.first.email == 'deleted@localhost.osem'
|
User.count == 1 && User.first.email == 'deleted@localhost.osem'
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,6 @@
|
||||||
You are registered for #{pluralize(@registration.events.count, 'event')}.
|
You are registered for #{pluralize(@registration.events.count, 'event')}.
|
||||||
They are at the end of this list.
|
They are at the end of this list.
|
||||||
- @registration.events_ordered.each do |event|
|
- @registration.events_ordered.each do |event|
|
||||||
= render 'event', event: event, event_schedule: event.event_schedules.first
|
= render 'conference_registrations/event', event: event, event_schedule: event.event_schedules.first
|
||||||
|
|
||||||
= render 'conferences/code_of_conduct', organization: @conference.organization
|
= render 'conferences/code_of_conduct', organization: @conference.organization
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,9 @@
|
||||||
|
|
||||||
= speaker_selector_input f
|
= speaker_selector_input f
|
||||||
|
|
||||||
|
- if current_user.manages_volunteers?(@conference)
|
||||||
|
= volunteer_selector_input f
|
||||||
|
|
||||||
= track_selector_input f
|
= track_selector_input f
|
||||||
|
|
||||||
= f.input :event_type_id, as: :select,
|
= f.input :event_type_id, as: :select,
|
||||||
|
|
@ -67,8 +70,8 @@
|
||||||
|
|
||||||
:javascript
|
:javascript
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
$('#event_speaker_ids').selectize({
|
$('.js-userSelector').selectize({
|
||||||
plugins: ['remove_button'],
|
plugins: ['remove_button'],
|
||||||
maxItems: 100
|
maxItems: 100
|
||||||
} )
|
})
|
||||||
});
|
});
|
||||||
|
|
|
||||||
19
app/views/proposals/_speaker_info.haml
Normal file
19
app/views/proposals/_speaker_info.haml
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
.speakerinfo
|
||||||
|
.row
|
||||||
|
.col-md-4
|
||||||
|
= image_tag speaker.profile_picture(:size => 120), class: 'img-responsive img-rounded'
|
||||||
|
.col-md-8
|
||||||
|
%h4
|
||||||
|
= link_to speaker.name, user_path(speaker.id)
|
||||||
|
%br
|
||||||
|
- if speaker.email_public?
|
||||||
|
= mail_to "#{ speaker.email }" do
|
||||||
|
%i.fa.fa-envelope-o.fa-2x
|
||||||
|
- if speaker.affiliation?
|
||||||
|
.text-muted
|
||||||
|
from
|
||||||
|
= speaker.affiliation
|
||||||
|
- if speaker.biography?
|
||||||
|
.row.speakerbio
|
||||||
|
.col-md-12
|
||||||
|
= markdown(speaker.biography)
|
||||||
11
app/views/proposals/_volunteer_info.haml
Normal file
11
app/views/proposals/_volunteer_info.haml
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
.speakerinfo
|
||||||
|
.row
|
||||||
|
.col-md-4
|
||||||
|
= image_tag speaker.profile_picture(:size => 120), class: 'img-responsive img-rounded'
|
||||||
|
.col-md-8
|
||||||
|
%h4
|
||||||
|
= link_to speaker.name, user_path(speaker.id)
|
||||||
|
- if speaker.affiliation?
|
||||||
|
.text-muted
|
||||||
|
from
|
||||||
|
= speaker.affiliation
|
||||||
19
app/views/proposals/_volunteers_table.haml
Normal file
19
app/views/proposals/_volunteers_table.haml
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
%table.table.table-striped#events
|
||||||
|
- events.each do |event|
|
||||||
|
%tr
|
||||||
|
%td.col-md-7{style: "padding:20px 8px 20px 8px;"}
|
||||||
|
= link_to event.title, conference_program_proposal_path(@conference.short_title, event.id)
|
||||||
|
%br
|
||||||
|
%small.text-muted
|
||||||
|
= event.event_type.title
|
||||||
|
= "(#{event.event_type.length} min)"
|
||||||
|
= "in #{event.track.name}" if event.track
|
||||||
|
- if event.require_registration
|
||||||
|
%br
|
||||||
|
= link_to registered_text(event), registrations_conference_program_proposal_path(@conference.short_title, event), class: 'btn btn-xs btn-danger'
|
||||||
|
|
||||||
|
%td.col-md-2{style: "padding:20px 8px 20px 8px;"}
|
||||||
|
- event_schedule = event.event_schedules.find_by(schedule_id: @program.selected_schedule_id)
|
||||||
|
- if event_schedule.present?
|
||||||
|
= inyourtz(event_schedule.start_time, @conference.timezone) do
|
||||||
|
= event_schedule.start_time.strftime("%Y %B %e - %H:%M")
|
||||||
|
|
@ -70,6 +70,9 @@
|
||||||
%span{ title: event.state.humanize, class: "fa #{status_icon(event)}" }
|
%span{ title: event.state.humanize, class: "fa #{status_icon(event)}" }
|
||||||
|
|
||||||
%td.col-md-7{style: "padding:20px 8px 20px 8px;"}
|
%td.col-md-7{style: "padding:20px 8px 20px 8px;"}
|
||||||
|
- if event.volunteers.include?(current_user)
|
||||||
|
%strong You are volunteer host for:
|
||||||
|
%br
|
||||||
= link_to event.title, conference_program_proposal_path(@conference.short_title, event.id)
|
= link_to event.title, conference_program_proposal_path(@conference.short_title, event.id)
|
||||||
%br
|
%br
|
||||||
%small.text-muted
|
%small.text-muted
|
||||||
|
|
@ -113,6 +116,13 @@
|
||||||
method: :patch, class: 'btn btn-mini btn-success', id: "review_event_#{event.id}"
|
method: :patch, class: 'btn btn-mini btn-success', id: "review_event_#{event.id}"
|
||||||
= link_to 'Edit', edit_conference_program_proposal_path(@conference.short_title, event.id),
|
= link_to 'Edit', edit_conference_program_proposal_path(@conference.short_title, event.id),
|
||||||
class: 'btn btn-default', id: "edit_proposal_#{event.id}"
|
class: 'btn btn-default', id: "edit_proposal_#{event.id}"
|
||||||
|
|
||||||
|
- if @volunteer_events.any?
|
||||||
|
%h2
|
||||||
|
Volunteer Events
|
||||||
|
%small
|
||||||
|
Thanks for being a host at #{@conference.title}
|
||||||
|
= render 'volunteers_table', events: @volunteer_events
|
||||||
.row
|
.row
|
||||||
.col-md-12
|
.col-md-12
|
||||||
- if can? :create, @event
|
- if can? :create, @event
|
||||||
|
|
|
||||||
|
|
@ -29,29 +29,20 @@
|
||||||
|
|
||||||
.row
|
.row
|
||||||
.col-md-3
|
.col-md-3
|
||||||
%h3
|
|
||||||
- if @event.speakers.any?
|
- if @event.speakers.any?
|
||||||
Presented by:
|
%h3
|
||||||
|
Presented by:
|
||||||
- @speakers_ordered.each do |speaker|
|
- @speakers_ordered.each do |speaker|
|
||||||
.speakerinfo
|
= render 'speaker_info', speaker: speaker
|
||||||
.row
|
/ end speakers.
|
||||||
.col-md-4
|
- if @event.volunteers.any?
|
||||||
= image_tag speaker.profile_picture(:size => 120), class: 'img-responsive img-rounded'
|
%h3
|
||||||
.col-md-8
|
Volunteer Hosts
|
||||||
%h4
|
%br
|
||||||
= link_to speaker.name, user_path(speaker.id)
|
%small Thanks for helping with #{@conference.title}!
|
||||||
%br
|
- @event.volunteers.each do |volunteer|
|
||||||
- if speaker.email_public?
|
= render 'volunteer_info', speaker: volunteer, show_bio: false
|
||||||
= mail_to "#{ speaker.email }" do
|
|
||||||
%i.fa.fa-envelope-o.fa-2x
|
|
||||||
- if speaker.affiliation?
|
|
||||||
.text-muted
|
|
||||||
from
|
|
||||||
= speaker.affiliation
|
|
||||||
-if speaker.biography?
|
|
||||||
.row.speakerbio
|
|
||||||
.col-md-12
|
|
||||||
= markdown(speaker.biography)
|
|
||||||
.col-md-9
|
.col-md-9
|
||||||
.row
|
.row
|
||||||
.col-md-12
|
.col-md-12
|
||||||
|
|
@ -93,9 +84,10 @@
|
||||||
.col-md-12
|
.col-md-12
|
||||||
%dt Conference:
|
%dt Conference:
|
||||||
%dd= link_to @event.program.conference.title, conference_path(@conference)
|
%dd= link_to @event.program.conference.title, conference_path(@conference)
|
||||||
.col-md-12
|
- if @event.language
|
||||||
%dt Language:
|
.col-md-12
|
||||||
%dd= @event.language if @event.language
|
%dt Language:
|
||||||
|
%dd= @event.language
|
||||||
.col-md-12
|
.col-md-12
|
||||||
%dt Track:
|
%dt Track:
|
||||||
%dd
|
%dd
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue