Schedules!

This commit is contained in:
Godwin
2015-09-26 20:05:55 -07:00
parent 34e72144cc
commit bc80c09938
82 changed files with 1669 additions and 268 deletions
+244 -2
View File
@@ -88,7 +88,6 @@ button,
&.register {
background-color: $colour-4;
//@include _(text-shadow, 0 0 0.15em rgba(0, 0, 0, 0.5));
}
form.logout & {
@@ -102,6 +101,10 @@ button,
#main &.delete {
background-color: $colour-4;
}
#main &.secondary {
background-color: $colour-1;
}
}
a.button {
@@ -505,12 +508,16 @@ input {
padding: 0 0.25em;
font-weight: normal;
@include font-family(secondary);
@include _(text-stroke, 0.5px #000)
@include _(text-stroke, 0.5px #000);
}
.date-labels {
float: left;
}
.date-field {
overflow: auto;
}
}
form {
@@ -530,6 +537,10 @@ form {
vertical-align: middle;
}
&.left {
text-align: left;
}
&.right {
text-align: right;
@@ -1940,3 +1951,234 @@ html[data-lingua-franca-example="html"] {
float: left;
}
}
.conferences-edit_schedule {
#main {
.location {
padding-top: 0.25em;
}
.errors {
padding: 0.25em;
background-color: $colour-2;
color: $white;
@include _(text-stroke, 0.5px #000);
}
.conflict-score {
padding: 0.25em;
background-color: $colour-3;
color: #333;
}
.all-workshops, .all-events {
list-style: none;
padding: 0;
li {
margin: 0.5em;
padding: 0.5em;
border: 1px solid #CCC;
background-color: lighten($colour-1, 35);
@include default-box-shadow(top, 2);
&.error {
outline: 0.2em solid $colour-2;
outline-offset: -0.2em;
}
}
h3 {
margin: 0;
}
.workshop-interest {
color: #888;
text-align: left;
margin: 0.25em 0;
}
.error-description {
background-color: $colour-2;
color: $white;
padding: 0.5em;
margin-top: 0.5em;
}
.warnings {
background-color: $colour-3;
color: #333;
padding: 0.5em;
margin-top: 0.5em;
list-style: none;
li {
padding: 0;
margin: 0;
background-color: transparent;
@include _(box-shadow, none);
}
}
}
.day_parts {
list-style: none;
h4 {
display: inline-block;
min-width: 12.5em;
margin: 0.25em 0;
}
select, .select {
float: right;
min-width: 5em;
}
.select {
padding-left: 0.25em;
}
}
.actions {
margin: 2em;
}
.unsaved {
@include font-family(secondary);
background-color: lighten($colour-3, 25);
margin: 0 5em 2em;
padding: 0.5em;
}
.all-events {
li {
background-color: lighten($colour-5, 35);
&.meal {
background-color: lighten($colour-3, 25);
}
}
h3 {
margin-bottom: 0.5em;
}
}
}
}
.programme {
.schedule {
width: auto;
margin: 0;
min-width: 100%;
@include _(box-shadow, none);
table-layout: fixed;
border-spacing: 0.25em;
border-collapse: separate;
td {
position: relative;
vertical-align: middle;
.title {
text-align: center;
@include font-family(secondary);
color: #666;
}
&.previewable {
cursor: pointer;
&:hover {
@include default-box-shadow(top, 2);
}
}
&.workshop {
background-color: lighten($colour-1, 35);
border: 0.25em solid $colour-1;
.preview {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
@include after {
display: none;
}
}
}
&.event {
background-color: lighten($colour-5, 35);
border: 0.25em solid $colour-5;
}
&.meal {
background-color: lighten($colour-3, 25);
border: 0.25em solid $colour-3;
}
&.not-interested {
opacity: 0.5;
}
.info {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 1000;
background-color: $white;
text-align: left;
overflow-y: auto;
@include _(transition, transform 250ms ease-in-out);
@include _(transform-origin, center bottom);
@include _(transform, rotate(180deg) translate3d(0, 0, 0));
.close {
float: right;
font-size: 2em;
@include before {
content: '×';
padding: 0 0.5em;
}
@include after {
display: none;
}
}
h2 {
margin-bottom: 0.5em;
}
}
&:target .info {
@include _(transform, rotate(0) translate3d(0, 0, 0));
}
}
}
.programme-day {
margin-top: 2em;
}
.programme-day-part {
overflow-x: auto;
}
}
.select-field {
line-height: 1.75em;
select {
display: block;
width: 100%;
height: 2.1em;
font-family: inherit;
font-size: 1.5em;
padding: 0.25em;
@include default-box-shadow(top, 1.5, false);
}
}
+1 -1
View File
@@ -7,7 +7,7 @@ $sidebar-width: rems(19);
// $colour-5: #8EA604;
$colour-1: #00ADEF; // blue
$colour-2: #DD57EF; // pink
$colour-2: #EF57B4; // #DD57EF; // pink
$colour-3: #E6C74B; // yellow
$colour-4: #D89E59; // orange
$colour-5: #02CA9E; // green
+17
View File
@@ -4,6 +4,8 @@ module ActiveRecord
end
class ApplicationController < LinguaFrancaApplicationController
include ScheduleHelper
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception, :except => [:do_confirm]
@@ -35,6 +37,21 @@ class ApplicationController < LinguaFrancaApplicationController
super
end
def home
@workshops = Workshop.where(:conference_id => @conference.id)
if @conference.workshop_schedule_published
@events = Event.where(:conference_id => @conference.id)
schedule = get_schedule_data
@schedule = schedule[:schedule]
@locations = Hash.new
EventLocation.where(:conference_id => @conference.id).each do |l|
@locations[l.id.to_s] = l
end
@day_parts = @conference.day_parts ? JSON.parse(@conference.day_parts) : {:morning => 0, :afternoon => 13, :evening => 18}
end
end
def policy
@is_policy_page = true
end
+268 -2
View File
@@ -2,6 +2,8 @@ require 'geocoder/calculations'
require 'rest_client'
class ConferencesController < ApplicationController
include ScheduleHelper
before_action :set_conference, only: [:show, :edit, :update, :destroy, :registrations]
before_filter :authenticate, only: [:registrations]
@@ -890,8 +892,8 @@ class ConferencesController < ApplicationController
can_edit = workshop.can_edit?(current_user)
do_403 unless can_edit || workshop.can_translate?(current_user, I18n.locale)
workshop.title = params[:title]
workshop.info = params[:info]
workshop.title = params[:title]
workshop.info = params[:info]
if can_edit
# dont allow translators to edit these fields
@@ -1033,6 +1035,269 @@ class ConferencesController < ApplicationController
return redirect_to view_workshop_url(@this_conference.slug, params[:workshop_id])
end
def schedule
set_conference
do_404 unless @this_conference.workshop_schedule_published || @this_conference.host?(current_user)
@events = Event.where(:conference_id => @this_conference.id)
@locations = EventLocation.where(:conference_id => @this_conference.id)
render 'schedule/show'
end
def edit_schedule
set_conference
set_conference_registration
do_404 unless @this_conference.host?(current_user)
@workshops = Workshop.where(:conference_id => @this_conference.id)
@events = Event.where(:conference_id => @this_conference.id)
if session[:workshops]
(0...@workshops.count).each do |i|
id = @workshops[i].id
w = session[:workshops][id.to_s]
if w
@workshops[i].start_time = w[:start_time]
@workshops[i].end_time = w[:end_time]
@workshops[i].event_location_id = w[:event_location_id]
end
end
end
if session[:events]
(0...@events.count).each do |i|
id = @events[i].id
w = session[:events][id.to_s]
if w
@events[i].start_time = w[:start_time]
@events[i].end_time = w[:end_time]
@events[i].event_location_id = w[:event_location_id]
end
end
end
@locations = EventLocation.where(:conference_id => @this_conference.id)
@location_hash = Hash.new
@locations.each do |l|
@location_hash[l.id.to_s] = l
end
@days = Array.new
start_day = @this_conference.start_date.strftime('%u').to_i
end_day = start_day + ((@this_conference.end_date - @this_conference.start_date) / 86400)
(start_day..end_day).each do |i|
@days << [(@this_conference.start_date + (i - start_day).days).strftime('%a'), ((i + 1) - start_day)]
end
@hours = Array.new
(0..48).each do |i|
hour = (Date.today + (i / 2.0).hours).strftime('%R')
@hours << hour
end
@event_durations = [['30 mins', 30], ['1 hour', 60], ['1.5 hours', 90], ['2 hours', 120], ['2.5 hours', 150]]
@workshop_durations = [['1 hour', 60], ['1.5 hours', 90], ['2 hours', 120]]
schedule_data = get_schedule_data
@schedule = schedule_data[:schedule]
@errors = schedule_data[:errors]
@warnings = schedule_data[:warnings]
@conflict_score = schedule_data[:conflict_score]
@error_count = schedule_data[:error_count]
if session[:day_parts]
@day_parts = JSON.parse(session[:day_parts])
elsif @this_conference.day_parts
@day_parts = JSON.parse(@this_conference.day_parts)
else
@day_parts = {:morning => 0, :afternoon => 13, :evening => 18}
end
@saved = session[:workshops].nil?
render 'schedule/edit'
end
def save_schedule
set_conference
do_404 unless @this_conference.host?(current_user)
@days = Array.new
start_day = @this_conference.start_date.strftime('%u').to_i
end_day = start_day + ((@this_conference.end_date - @this_conference.start_date) / 86400)
(start_day..end_day).each do |i|
@days << [(@this_conference.start_date + (i - start_day).days).strftime('%a'), i]
end
@workshops = Workshop.where(:conference_id => @this_conference.id)
@events = Event.where(:conference_id => @this_conference.id)
@locations = EventLocation.where(:conference_id => @this_conference.id)
do_save = (params[:button] == 'save' || params[:button] == 'publish')
session[:workshops] = do_save ? nil : Hash.new
session[:events] = do_save ? nil : Hash.new
session[:day_parts] = do_save ? nil : Hash.new
(0...@workshops.count).each do |i|
id = @workshops[i].id.to_s
if params[:workshop_day][id].present? && params[:workshop_hour][id].present? && params[:workshop_duration][id].present?
date = @this_conference.start_date + (params[:workshop_day][id].to_i - 1).days
h = params[:workshop_hour][id].split(':')
date = date.change({hour: h.first, minute: h.last})
@workshops[i].start_time = date
@workshops[i].end_time = date + (params[:workshop_duration][id].to_i).minutes
else
@workshops[i].start_time = nil
@workshops[i].end_time = nil
end
@workshops[i].event_location_id = params[:workshop_location][id]
if do_save
@workshops[i].save
else
session[:workshops][id] = {
:start_time => @workshops[i].start_time,
:end_time => @workshops[i].end_time,
:end_time => @workshops[i].end_time,
:event_location_id => @workshops[i].event_location_id
}
end
end
(0...@events.count).each do |i|
id = @events[i].id.to_s
if params[:event_day][id].present? && params[:event_hour][id].present? && params[:event_duration][id].present?
date = @this_conference.start_date + (params[:event_day][id].to_i - 1).days
h = params[:event_hour][id].split(':')
date = date.change({hour: h.first, minute: h.last})
@events[i].start_time = date
@events[i].end_time = date + (params[:event_duration][id].to_i).minutes
else
@events[i].start_time = nil
@events[i].end_time = nil
end
@events[i].event_location_id = params[:event_location][id]
if do_save
@events[i].save
else
session[:events][id] = {
:start_time => @events[i].start_time,
:end_time => @events[i].end_time,
:end_time => @events[i].end_time,
:event_location_id => @events[i].event_location_id
}
end
end
if params[:day_parts]
day_parts = {:morning => 0}
params[:day_parts].each do |part, h|
h = h.split(':')
day_parts[part.to_sym] = h[0].to_f + (h[1].to_i > 0 ? 0.5 : 0)
end
if do_save
@this_conference.day_parts = day_parts.to_json
else
session[:day_parts] = day_parts.to_json
end
end
save_conference = do_save
if params[:button] == 'publish'
@this_conference.workshop_schedule_published = true
save_conference = true
elsif params[:button] == 'unpublish'
@this_conference.workshop_schedule_published = false
save_conference = true
end
if save_conference
@this_conference.save
end
redirect_to edit_schedule_url(@this_conference.slug)
end
def add_event
set_conference
set_conference_registration
do_404 unless @this_conference.host?(current_user)
render 'events/edit'
end
def edit_event
set_conference
set_conference_registration
do_404 unless @this_conference.host?(current_user)
@event = Event.find(params[:id])
do_403 unless @event.conference_id == @this_conference.id
render 'events/edit'
end
def save_event
set_conference
do_404 unless @this_conference.host?(current_user)
if params[:event_id]
event = Event.find(params[:event_id])
do_403 unless event.conference_id == @this_conference.id
else
event = Event.new(:conference_id => @this_conference.id)
end
event.title = params[:title]
event.info = params[:info]
event.event_type = params[:event_type]
event.save
return redirect_to schedule_url(@this_conference.slug)
end
def add_location
set_conference
set_conference_registration
do_404 unless @this_conference.host?(current_user)
render 'event_locations/edit'
end
def edit_location
set_conference
set_conference_registration
do_404 unless @this_conference.host?(current_user)
@location = EventLocation.find(params[:id])
do_403 unless @location.conference_id == @this_conference.id
@amenities = JSON.parse(@location.amenities || '[]').map &:to_sym
render 'event_locations/edit'
end
def save_location
set_conference
do_404 unless @this_conference.host?(current_user)
if params[:location_id]
location = EventLocation.find(params[:location_id])
do_403 unless location.conference_id == @this_conference.id
else
location = EventLocation.new(:conference_id => @this_conference.id)
end
location.title = params[:title]
location.address = params[:address]
location.amenities = (params[:needs] || {}).keys.to_json
location.save
return redirect_to schedule_url(@this_conference.slug)
end
# DELETE /conferences/1
#def destroy
# @conference.destroy
@@ -1053,6 +1318,7 @@ class ConferencesController < ApplicationController
register_path(@this_conference.slug) => 'registration.Registration',
workshops_path(@this_conference.slug) => 'registration.Workshops'
}
@submenu[schedule_path(@this_conference.slug)] = 'registration.Schedule' if @this_conference.workshop_schedule_published || @is_host
if @is_host
@submenu[edit_conference_path(@this_conference.slug)] = 'registration.Edit'
@submenu[stats_path(@this_conference.slug)] = 'registration.Stats'
+2
View File
@@ -1,6 +1,8 @@
require 'redcarpet'
module ApplicationHelper
include ScheduleHelper
@@keyQueue = nil
@@translationsOnThisPage = nil
@@lastTranslation = nil
+146
View File
@@ -0,0 +1,146 @@
module ScheduleHelper
def get_schedule_data
schedule = Hash.new
workshop_errors = Hash.new
workshop_warnings = Hash.new
all_events = (@workshops + @events)
conflicts = 0
errors = 0
(0...all_events.count).each do |i|
w = all_events[i]
if w.start_time.present? && w.end_time.present? && w.event_location_id.present?
type = w.is_a?(Workshop) ? :workshop : :event
hour = w.start_time.strftime('%H').to_i
hour += 0.5 if w.start_time.strftime('%M').to_i > 15
end_hour = w.end_time.strftime('%H').to_i
end_hour += 0.5 if w.end_time.strftime('%M').to_i > 15
day = w.conference_day
schedule[day] ||= Hash.new
schedule[day][:locations] ||= Hash.new
schedule[day][:locations][w.event_location_id] ||= Hash.new
conflict = nil
(hour...end_hour).step(0.5).each do |h|
h = h.to_i if h == h.to_i
if !conflict && schedule[day][:locations][w.event_location_id][h].present?
conflict = schedule[day][:locations][w.event_location_id][h]
end
end
if conflict.present?
w_conflict = get_workshop(conflict, @workshops, @events)
workshop_errors[(w_conflict.is_a?(Workshop) ? 'w' : 'e') + w_conflict.id.to_s] = "Time conflict with &ldquo;<strong>#{w_conflict.title}</strong>&rdquo;".html_safe
workshop_errors[(w.is_a?(Workshop) ? 'w' : 'e') + w.id.to_s] = "Time conflict with &ldquo;<strong>#{w.title}</strong>&rdquo;".html_safe
errors += 1 if workshop_errors[(w_conflict.is_a?(Workshop) ? 'w' : 'e') + w_conflict.id.to_s].nil?
else
schedule[day][:start_time] = hour if schedule[day][:start_time].nil? || hour < schedule[day][:start_time]
schedule[day][:end_time] = end_hour if schedule[day][:end_time].nil? || end_hour > schedule[day][:end_time]
schedule[day][:locations][w.event_location_id][hour] = {
:span => w.duration / 60.0,
:type => w.is_a?(Event) ? w.event_type : :workshop
}
schedule[day][:locations][w.event_location_id][hour][:workshop] = i if type == :workshop
schedule[day][:locations][w.event_location_id][hour][:event] = (i - @workshops.count) if type == :event
end
else
workshop_warnings["w#{w.id}"] ||= Array.new
workshop_warnings["w#{w.id}"] << (w.is_a?(Workshop) ? "This workshop is not scheduled" : "This event is not scheduled")
end
end
schedule.each do |day, day_data|
day_data[:locations].each do |location1, location_data1|
location_data1.each do |time1, data1|
day_data[:locations].each do |location2, location_data2|
location_data2.each do |time2, data2|
if data1[:workshop].present?
if data2[:workshop].present?
unless location1 == location2 && time1 == time2
if workshop_errors[data1[:workshop]].nil?
w1 = @workshops[data1[:workshop]]
w2 = @workshops[data2[:workshop]]
if time1 == time2
w1.workshop_facilitators.each do |f|
u = User.find(f.user_id)
if w2.active_facilitator?(u)
errors += 1 if workshop_errors[(w2.is_a?(Workshop) ? 'w' : 'e') + w2.id.to_s].nil?
workshop_errors["w#{w1.id}"] = "This workshop shares facilitators with &ldquo;<strong>#{w2.title}</strong>&rdquo;".html_safe
end
end
connection ||= ActiveRecord::Base.connection
common_interest_count = connection.select_value("SELECT COUNT(w1.user_id) FROM workshop_interests AS w1 JOIN workshop_interests AS w2 ON w2.user_id=w1.user_id WHERE w1.workshop_id=#{w1.id} AND w2.workshop_id=#{w2.id}")
common_interest_count = common_interest_count ? common_interest_count.to_i : 0
if common_interest_count > 0
conflicts += common_interest_count
workshop_warnings["w#{w1.id}"] ||= Array.new
workshop_warnings["w#{w1.id}"] << "<strong>#{common_interest_count}</strong> people are also interested in &ldquo;<strong>#{w2.title}</strong>&rdquo;".html_safe
end
end
end
end
end
end
end
end
end
end
end
{
:schedule => schedule.sort,
:errors => workshop_errors,
:warnings => workshop_warnings,
:conflict_score => conflicts,
:error_count => errors
}
end
def get_workshop(workshop, workshops, events)
workshop[:workshop] ? workshops[workshop[:workshop]] : (events[workshop[:event]] || :event)
end
def workshop_classes(workshop, show_interest)
classes = [workshop.is_a?(Workshop) ? :workshop : workshop.event_type]
if show_interest && workshop.is_a?(Workshop) && current_user && WorkshopInterest.where(:user_id => current_user.id)
if workshop.interested?(current_user) || workshop.facilitator?(current_user)
classes << 'interested'
else
classes << 'not-interested'
end
end
return classes
end
def schedule_start_and_end_times(day_part, day_parts, day_schedule)
start_time = [day_parts[day_parts.keys[day_part]], day_schedule[:start_time]].max
end_time = [day_parts[day_parts.keys[day_part + 1]] || 24, day_schedule[:end_time]].min
min_time = nil
max_time = nil
day_schedule[:locations].each do |location, location_schedule|
location_schedule.each do |hour, workshop|
t_start = hour
t_end = hour + workshop[:span]
if t_start >= start_time && t_end <= end_time
min_time = [min_time || 24, t_start].min
max_time = [max_time || 0, t_end].max
end
end
end
return nil unless min_time.present? && max_time.present?
[min_time || 0, max_time || 24]
end
end
+17 -2
View File
@@ -1,2 +1,17 @@
class Event < ActiveRecord::Base
end
class Event < ActiveRecord::Base
belongs_to :conference
def conference_day
return nil unless start_time.present? && end_time.present?
start_day = conference.start_date.change(hour: 0, minute: 0, second: 0)
w_start_day = start_time.change(hour: 0, minute: 0, second: 0)
return (((w_start_day - start_day) / 86400) + 1).to_i
end
def duration
return nil unless start_time.present? && end_time.present?
((end_time - start_time) / 60).to_i
end
end
+2
View File
@@ -0,0 +1,2 @@
class EventLocation < ActiveRecord::Base
end
+13
View File
@@ -87,6 +87,19 @@ class Workshop < ActiveRecord::Base
(user.can_translate? && lang.to_sym != locale.to_sym) || can_edit?(user)
end
def conference_day
return nil unless start_time.present? && end_time.present?
start_day = conference.start_date.change(hour: 0, minute: 0, second: 0)
w_start_day = start_time.change(hour: 0, minute: 0, second: 0)
return (((w_start_day - start_day) / 86400) + 1).to_i
end
def duration
return nil unless start_time.present? && end_time.present?
((end_time - start_time) / 60).to_i
end
private
def make_slug
if !self.slug
+16 -12
View File
@@ -4,16 +4,20 @@
%article
%h2=_!@conference.title
=@conference.info.html_safe
%h3=_'articles.workshops.headings.Proposed_Workshops'
%p=_'articles.workshops.paragraphs.Proposed_Workshops', "Would you like to facilitate your own workshop? Simply register and visit the workshops page. If you have already registered you can access the page by restarting the registration process."
- if @conference.workshops
%ul.workshop-list
- @conference.workshops.sort_by{|w| w.title}.each do |w|
%li
%h4=w.title
.workshop-interest
- if w.interested?(current_user)
=_'articles.workshops.info.you_are_interested_count', "You and #{w.interested_count - 1} others are interested in this workshop", :vars => {:count => (w.interested_count - 1)}
- elsif w.interested_count > 0
=_'articles.workshops.info.interested_count', "#{w.interested_count} people are interested in this workshop", :vars => {:count => w.interested_count}
.workshop-description=markdown w.info
- if @schedule
%h3=_'articles.workshops.headings.Schedule'
= render 'schedule/programme', :schedule => @schedule, :conference => @conference, :workshops => @workshops, :events => @events, :locations => @locations, :show_interest => true, :day_parts => @day_parts, :show_previews => true
- else
%h3=_'articles.workshops.headings.Proposed_Workshops'
%p=_'articles.workshops.paragraphs.Proposed_Workshops', "Would you like to facilitate your own workshop? Simply register and visit the workshops page. If you have already registered you can access the page by restarting the registration process."
%ul.workshop-list
- @conference.workshops.sort_by{|w| w.title}.each do |w|
%li
%h4=w.title
.workshop-interest
- if w.interested?(current_user)
=_'articles.workshops.info.you_are_interested_count', "You and #{w.interested_count - 1} others are interested in this workshop", :vars => {:count => (w.interested_count - 1)}
- elsif w.interested_count > 0
=_'articles.workshops.info.interested_count', "#{w.interested_count} people are interested in this workshop", :vars => {:count => w.interested_count}
.workshop-description=markdown w.info
+23
View File
@@ -0,0 +1,23 @@
= render 'conferences/page_header', :page_key => (@location ? 'Edit_Location' : 'New_Location')
%article
= form_tag save_location_path(@this_conference.slug), class: 'composition' do
= row do
= columns(medium: 12) do
= (hidden_field_tag :location_id, @location.id) if @location
.text-field.input-field.big
= label_tag :title
= text_field_tag :title, @location ? @location.title : nil, :required => true
= row do
= columns(medium: 6) do
.text-area-field.input-field
= label_tag :address
= text_area_tag :address, @location ? @location.address : nil, :required => true
= columns(medium: 6) do
%h3=_'articles.locations.headings.amenities'
- [:sound, :projector, :tools].each do |need|
.single-check-box-field.input-field
= label_tag "needs_#{need}" do
= check_box_tag "needs[#{need}]", 1, @location && @amenities.include?(need)
= _"workshop.options.needs.#{need}"
.actions
= button_tag :save, :value => :save
+22 -7
View File
@@ -1,7 +1,22 @@
%h1 Editing event
= render 'form'
= link_to 'Show', @event
\|
= link_to 'Back', events_path
= render 'conferences/page_header', :page_key => (@event ? 'Edit_Event' : 'New_Event')
%article
= form_tag save_event_path(@this_conference.slug), class: 'composition' do
= row do
= columns(medium: 9) do
= (hidden_field_tag :event_id, @event.id) if @event
.text-field.input-field.big
= label_tag :title
= text_field_tag :title, @event ? @event.title : nil, :required => true
= columns(medium: 3) do
.select-field.input-field
= label_tag :event_type do
= select_tag :event_type, options_for_select([:event, :meal], @event ? @event.event_type : nil), :include_blank => true
=_'forms.labels.generic.event_type'
= row do
= columns(medium: 12) do
.text-area-field.input-field
= label_tag :info
= text_area_tag :info, @event ? @event.info : nil, :required => true
= columns(medium: 12) do
.actions.right
= button_tag :save, :value => :save
+36
View File
@@ -0,0 +1,36 @@
.programme
- schedule.each do |day, day_schedule|
.programme-day
%h2=I18n.l(conference.start_date + (day - 1).days, :format => "%A")
- (0...day_parts.length).each do |day_part|
.programme-day-part
- times = schedule_start_and_end_times(day_part, day_parts, day_schedule)
- if times.present?
%h3=_"articles.headings.schedule.day_parts.#{day_parts.keys[day_part].to_s}" if day_parts.length > 1
%table.schedule
%tr
%th
- (times.first...times.last).step(0.5).each do |t|
- t = t.to_i if t == t.to_i
%th=I18n.l(Date.today + t.hours, :format => :short)
- day_schedule[:locations].each do |location, location_schedule|
%tr
%th=locations[location.to_s].title
- skip = 0
- (times.first...times.last).step(0.5).each do |t|
- t = t.to_i if t == t.to_i
- if location_schedule[t].present?
- workshop = location_schedule[t]
- w = get_workshop(workshop, workshops, events)
%td{:class => workshop_classes(w, show_interest) + [show_previews && workshop[:type] == :workshop ? 'previewable' : nil], :colspan => (workshop[:span] * 2), :id => "workshop-#{w.id}"}
.title= w.title
- if show_previews && workshop[:type] == :workshop
.info
%a.close{href: "#!"}
= render 'workshops/show', :workshop => w, :preview => true
%a{class: 'preview', href: "#workshop-#{w.id}"}
- skip = workshop[:span] - 0.5
- elsif skip > 0
- skip -= 0.5
- else
%td.empty
+77
View File
@@ -0,0 +1,77 @@
= render 'conferences/page_header', :page_key => 'Edit_Schedule'
%article
= form_tag save_schedule_path(@this_conference.slug), class: 'composition' do
= row do
= columns(medium: 12) do
= render 'schedule/programme', :schedule => @schedule, :conference => @this_conference, :workshops => @workshops, :events => @events, :locations => @location_hash, :show_interest => false, :day_parts => @day_parts, :show_previews => false
= row do
= columns(medium: 12) do
- if @error_count && @error_count > 0
%h3.errors
=_'errors.schedule.errors',"Errors:"
= @error_count
- if @conflict_score && @conflict_score > 0
%h3.conflict-score
=_'errors.schedule.conflict_score',"Interest Conflicts:"
= @conflict_score
= row do
= columns(medium: 12) do
= (hidden_field_tag :location_id, @location.id) if @location
.actions
- if @this_conference.workshop_schedule_published
= button_tag :Unpublish, :value => :unpublish, :class => 'delete'
- elsif @error_count < 1
= button_tag :Publish, :value => :publish
= button_tag :Preview, :value => :preview, :class => 'secondary'
- unless @this_conference.workshop_schedule_published && @error_count > 0
= button_tag :save, :value => :save
- unless @saved
.unsaved=_'errors.schedule.unsaved','Your changes will not be saved until you press Save or Publish'
= row do
= columns(medium: 6) do
%h2=_"articles.headings.schedule.day_parts.Workshops"
%ul.all-workshops
- @workshops.each do |i|
- error = @errors["w#{i.id}"]
- warnings = @warnings["w#{i.id}"]
%li{class: error.present? ? :error : nil}
%h3=i.title
.workshop-interest=_'articles.workshops.info.interested_count', "#{i.interested_count} people are interested in this workshop", :vars => {:count => i.interested_count}
.time
= select_tag "workshop_day[#{i.id}]", options_for_select(@days, i.conference_day), :include_blank => true
= select_tag "workshop_hour[#{i.id}]", options_for_select(@hours, i.start_time ? i.start_time.strftime('%R') : nil), :include_blank => true
= select_tag "workshop_duration[#{i.id}]", options_for_select(@workshop_durations, i.duration || 60)
.location
= select_tag "workshop_location[#{i.id}]", options_from_collection_for_select(@locations, :id, :title, i.event_location_id), :include_blank => true
- if warnings
%ul.warnings
- warnings.each do |warning|
%li=warning
- if error
.error-description=error
= columns(medium: 6) do
%h2=_"articles.headings.schedule.day_parts.Events"
%ul.all-events
- @events.each do |i|
- error = @errors["e#{i.id}"]
%li{:class => [i.event_type, error.present? ? :error : nil]}
%h3=i.title
.time
= select_tag "event_day[#{i.id}]", options_for_select(@days, i.conference_day)
= select_tag "event_hour[#{i.id}]", options_for_select(@hours, i.start_time ? i.start_time.strftime('%R') : '12:00')
= select_tag "event_duration[#{i.id}]", options_for_select(@event_durations, i.duration || 60)
.location
= select_tag "event_location[#{i.id}]", options_from_collection_for_select(@locations, :id, :title, i.event_location_id), :include_blank => true
- if error
.error-description=error
%h2=_"articles.headings.schedule.day_parts.Day_Parts"
%ul.day_parts
- [:morning, :afternoon, :evening].each do |day_part|
%li
%h4
=_"articles.headings.schedule.day_parts.#{day_part.to_s}"
- h = (Date.today + @day_parts[day_part.to_s].to_f.hours).strftime('%R')
- if day_part == :morning
.select=h
- else
= select_tag "day_parts[#{day_part.to_s}]", options_for_select(@hours, h)
+28
View File
@@ -0,0 +1,28 @@
= render 'conferences/page_header', :page_key => 'Schedule'
%article
- if @this_conference.host?(current_user)
= row do
= columns(medium: 12) do
.actions.left
= link_to (_'actions.schedule.edit','Edit Schedule'), edit_schedule_path(@this_conference.slug), class: [:button]
= row do
= columns(medium: 6) do
%h2=_'articles.schedule.headings.Events'
- if @events
%ul
- @events.each do |event|
%li
%h3=_!event.title
= link_to (_'actions.events.edit','Edit'), edit_event_path(@this_conference.slug, event.id), class: [:button, :modify]
.actions.left
= link_to (_'actions.events.create','Add Event'), add_event_path(@this_conference.slug), class: [:button, :modify]
= columns(medium: 6) do
%h2=_'articles.schedule.headings.Locations'
- if @locations
%ul
- @locations.each do |location|
%li
%h3=_!location.title
= link_to (_'actions.locations.edit','Edit'), edit_location_path(@this_conference.slug, location.id), class: [:button, :modify]
.actions.left
= link_to (_'actions.schedule.edit','Add Location'), add_location_path(@this_conference.slug), class: [:button, :modify]
+58
View File
@@ -0,0 +1,58 @@
= row do
= columns(medium: 12) do
%h2=_!workshop.title
.workshop-interest
- if workshop.interested?(current_user)
=_'articles.workshops.info.you_are_interested_count', "You and #{workshop.interested_count - 1} others are interested in this workshop", :vars => {:count => (workshop.interested_count - 1)}
- else
=_'articles.workshops.info.interested_count', "#{workshop.interested_count} people are interested in this workshop", :vars => {:count => workshop.interested_count}
- if !preview && workshop.can_show_interest?(current_user)
= form_tag toggle_workshop_interest_path(workshop.conference.slug, workshop.id) do
= button_tag (workshop.interested?(current_user) ? :remove_interest : :show_interest), :value => :toggle_interest, :class => (workshop.interested?(current_user) ? 'delete' : 'add')
=markdown _!(workshop.info) || ''
- if !preview && logged_in? && current_user.can_translate?
.actions
- I18n.backend.enabled_locales.each do |locale|
= (link_to (_'actions.workshops.Translate', "Translate into #{language_name(locale)}", :vars => {:language => language_name(locale)}), edit_workshop_url(workshop.conference.slug, workshop.id, url_params(locale)), :class => 'button translate') if workshop.can_translate?(current_user, locale)
= columns(medium: 6) do
%h3=_'articles.workshops.headings.facilitators'
.facilitators
- workshop.workshop_facilitators.each do |f|
- u = User.find(f.user_id)
- if logged_in? && (workshop.public_facilitator?(u) || f.user_id == current_user.id || workshop.active_facilitator?(current_user))
.facilitator
.name=_!(u.firstname || u.username || u.email)
.role
=_"roles.workshops.facilitator.#{workshop.role(u).to_s}"
- if !preview && f.role.to_sym == :requested && workshop.active_facilitator?(current_user)
=(link_to (_'actions.workshops.Approve'), approve_facilitate_workshop_request_path(workshop.conference.slug, workshop.id, f.user_id, 'approve'), :class => 'button modify')
=(link_to (_'actions.workshops.Deny'), approve_facilitate_workshop_request_path(workshop.conference.slug, workshop.id, f.user_id, 'deny'), :class => 'button delete')
- elsif !preview && (f.user_id == current_user.id && f.role.to_sym != :creator) || (!workshop.conference.registered?(u) && workshop.active_facilitator?(current_user))
=(link_to (_'actions.workshops.Remove'), approve_facilitate_workshop_request_path(workshop.conference.slug, workshop.id, f.user_id, 'remove'), :class => 'button delete')
- if !preview
.actions
=(link_to (_'actions.workshops.Facilitate'), facilitate_workshop_path(workshop.conference.slug, workshop.id), :class => 'button modify') if !workshop.facilitator?(current_user)
- if workshop.active_facilitator?(current_user)
= form_tag workshop_add_facilitator_path(workshop.conference.slug, workshop.id), :class => 'add-facilitator' do
%h4='Add a facilitator'
.email-field.input-field
= email_field_tag :email, nil, required: true
= label_tag :email
= button_tag :add
- if workshop.languages
= columns(medium: 6) do
%h3=_'articles.workshops.headings.languages','Workshop Language'
%p= _!((JSON.parse(workshop.languages || '[]').map { |x| _"languages.#{x}" }).join(', ').to_s.html_safe)
- if workshop.theme
= columns(medium: 6) do
%h3=_'articles.workshops.headings.theme','Theme'
%p= [:race_gender, :mechanics, :funding, :organization, :community].include?((workshop.theme || '').to_sym) ? (_"workshop.options.theme.#{workshop.theme}") : workshop.theme
- if workshop.active_facilitator?(current_user) || workshop.conference.host?(current_user)
- if workshop.needs
= columns(medium: 6) do
%h3=_'articles.workshops.headings.needs','What do you need?'
%p= _!((JSON.parse(workshop.needs || '[]').map { |x| _"workshop.options.needs.#{x}" }).join(', ').to_s.html_safe)
- if workshop.notes
= columns(medium: 12) do
%h3=_'articles.workshops.headings.notes','Notes'
=markdown _!(workshop.notes)
+1 -56
View File
@@ -1,62 +1,7 @@
= render 'conferences/page_header', :page_key => 'View_Workshop'
%article
= render 'workshops/show', :workshop => @workshop, :preview => false
= row do
= columns(medium: 12) do
%h2=_!@workshop.title
.workshop-interest
- if @workshop.interested?(current_user)
=_'articles.workshops.info.you_are_interested_count', "You and #{@workshop.interested_count - 1} others are interested in this workshop", :vars => {:count => (@workshop.interested_count - 1)}
- else
=_'articles.workshops.info.interested_count', "#{@workshop.interested_count} people are interested in this workshop", :vars => {:count => @workshop.interested_count}
- if @workshop.can_show_interest?(current_user)
= form_tag toggle_workshop_interest_path(@this_conference.slug, @workshop.id) do
= button_tag (@workshop.interested?(current_user) ? :remove_interest : :show_interest), :value => :toggle_interest, :class => (@workshop.interested?(current_user) ? 'delete' : 'add')
=markdown _!(@workshop.info) || ''
- if current_user.can_translate?
.actions
- I18n.backend.enabled_locales.each do |locale|
= (link_to (_'actions.workshops.Translate', "Translate into #{language_name(locale)}", :vars => {:language => language_name(locale)}), edit_workshop_url(@this_conference.slug, @workshop.id, url_params(locale)), :class => 'button translate') if @workshop.can_translate?(current_user, locale)
= columns(medium: 6) do
%h3=_'articles.workshops.headings.facilitators'
.facilitators
- @workshop.workshop_facilitators.each do |f|
- u = User.find(f.user_id)
- if @workshop.public_facilitator?(u) || f.user_id == current_user.id || @workshop.active_facilitator?(current_user)
.facilitator
.name=_!(u.firstname || u.username || u.email)
.role
=_"roles.workshops.facilitator.#{@workshop.role(u).to_s}"
- if f.role.to_sym == :requested && @workshop.active_facilitator?(current_user)
=(link_to (_'actions.workshops.Approve'), approve_facilitate_workshop_request_path(@this_conference.slug, @workshop.id, f.user_id, 'approve'), :class => 'button modify')
=(link_to (_'actions.workshops.Deny'), approve_facilitate_workshop_request_path(@this_conference.slug, @workshop.id, f.user_id, 'deny'), :class => 'button delete')
- elsif (f.user_id == current_user.id && f.role.to_sym != :creator) || (!@this_conference.registered?(u) && @workshop.active_facilitator?(current_user))
=(link_to (_'actions.workshops.Remove'), approve_facilitate_workshop_request_path(@this_conference.slug, @workshop.id, f.user_id, 'remove'), :class => 'button delete')
.actions
=(link_to (_'actions.workshops.Facilitate'), facilitate_workshop_path(@this_conference.slug, @workshop.id), :class => 'button modify') if !@workshop.facilitator?(current_user)
- if @workshop.active_facilitator?(current_user)
= form_tag workshop_add_facilitator_path(@this_conference.slug, @workshop.id), :class => 'add-facilitator' do
%h4='Add a facilitator'
.email-field.input-field
= email_field_tag :email, nil, required: true
= label_tag :email
= button_tag :add
- if @workshop.languages
= columns(medium: 6) do
%h3=_'articles.workshops.headings.languages','Workshop Language'
%p= _!((JSON.parse(@workshop.languages || '[]').map { |x| _"languages.#{x}" }).join(', ').to_s.html_safe)
- if @workshop.theme
= columns(medium: 6) do
%h3=_'articles.workshops.headings.theme','Theme'
%p= [:race_gender, :mechanics, :funding, :organization, :community].include?((@workshop.theme || '').to_sym) ? (_"workshop.options.theme.#{@workshop.theme}") : @workshop.theme
- if @workshop.active_facilitator?(current_user) || @this_conference.host?(current_user)
- if @workshop.needs
= columns(medium: 6) do
%h3=_'articles.workshops.headings.needs','What do you need?'
%p= _!((JSON.parse(@workshop.needs || '[]').map { |x| _"workshop.options.needs.#{x}" }).join(', ').to_s.html_safe)
- if @workshop.notes
= columns(medium: 12) do
%h3=_'articles.workshops.headings.notes','Notes'
=markdown _!(@workshop.notes)
= columns(medium: 12) do
.actions.right
= (link_to (_'actions.workshops.Edit'), edit_workshop_path(@this_conference.slug, @workshop.id), :class => 'button modify') if @workshop.can_edit?(current_user)